home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / term43-source.lha / Extras / Source / term-Source.lha / termMain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-20  |  102.2 KB  |  5,599 lines

  1. /*
  2. **    termMain.c
  3. **
  4. **    Program main routines and event loop
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Argument vectors offsets. */
  13.  
  14. enum    {    ARG_WINDOW,ARG_PUBSCREEN,ARG_STARTUP,ARG_PORTNAME,ARG_SETTINGS,ARG_UNIT,ARG_DEVICE,
  15.         ARG_NEW,ARG_SYNC,ARG_QUIET,ARG_BEHIND,ARG_DEBUG,ARG_LANGUAGE,
  16.  
  17.         ARG_COUNT
  18.     };
  19.  
  20.     /* Argument template. */
  21.  
  22. #define ARGTEMPLATE    "WINDOW/K,PUBSCREEN/K,STARTUP/K,PORTNAME/K,SETTINGS/K,UNIT/K/N,DEVICE/K,NEW/S,SYNC/S,QUIET/S,BEHIND/S,DEBUG/S,LANGUAGE/K"
  23.  
  24.     /* Local config path variable. */
  25.  
  26. STATIC STRPTR        ConfigPath;
  27. STATIC UBYTE __far    ThePath[MAX_FILENAME_LENGTH];
  28.  
  29.     /* Local dialing list. */
  30.  
  31. STATIC struct List    *LocalDialList;
  32. STATIC LONG         LocalCount = -1;
  33.  
  34.     /* Startup file name. */
  35.  
  36. STATIC UBYTE __far    StartupFile[MAX_FILENAME_LENGTH];
  37.  
  38.     /* Did we hang up the line? */
  39.  
  40. STATIC BOOLEAN        HungUp = FALSE;
  41.  
  42.     /* Poll OwnDevUnit.library for the device to become available again? */
  43.  
  44. STATIC BOOLEAN        PollODU = FALSE;
  45. STATIC UWORD        PollODUCount = 0;
  46.  
  47.     /* Cloned CLI data. */
  48.  
  49. STATIC struct CommandLineInterface    *LocalCLI;
  50. STATIC BPTR                 OldCLI;
  51.  
  52.     /* Segment split routine, has to be local. */
  53.  
  54. STATIC struct Process * __regargs    SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function);
  55. STATIC VOID                CloseLibs(VOID);
  56.  
  57.     /* main():
  58.      *
  59.      *    This is our main entry point, check for the right
  60.      *    Kickstart version and fire off the background task
  61.      *    if approritate.
  62.      */
  63.  
  64. LONG
  65. main()
  66. {
  67.     STRPTR Result;
  68.  
  69.         /* Are we running as a child of Workbench? */
  70.  
  71.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  72.  
  73.     if(!ThisProcess -> pr_CLI)
  74.     {
  75.         WaitPort(&ThisProcess -> pr_MsgPort);
  76.  
  77.         WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess -> pr_MsgPort);
  78.     }
  79.     else
  80.         WBenchMsg = NULL;
  81.  
  82.         /* Now try to open dos.library and utility.library and go on examining
  83.          * our calling parameters.
  84.          */
  85.  
  86.     if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
  87.     {
  88.         CloseLibs();
  89.  
  90.         return(RETURN_FAIL);
  91.     }
  92.  
  93.     if(!(UtilityBase = OpenLibrary("utility.library",0)))
  94.     {
  95.         CloseLibs();
  96.  
  97.         return(RETURN_FAIL);
  98.     }
  99.  
  100.         /* We were called from Shell. */
  101.  
  102.     if(ThisProcess -> pr_CLI)
  103.     {
  104.         STRPTR *ArgArray;
  105.  
  106.             /* Use the cute ReadArgs parser, allocate the
  107.              * argument vectors...
  108.              */
  109.  
  110.         if(ArgArray = (STRPTR *)AllocVec(sizeof(STRPTR) * (ARG_COUNT),MEMF_ANY|MEMF_CLEAR))
  111.         {
  112.             struct RDArgs *ArgsPtr;
  113.  
  114.             if(ArgsPtr = (struct RDArgs *)AllocDosObject(DOS_RDARGS,TAG_DONE))
  115.             {
  116.                 ArgsPtr -> RDA_ExtHelp =    "\nUsage: term [WINDOW <Name>] [PUBSCREEN <Name>] [STARTUP <File name>]\n"
  117.                                 "            [SETTINGS <File or path name>] [UNIT <Number>] [DEVICE <Name>]\n"
  118.                                 "            [NEW] [SYNC] [QUIET] [BEHIND] [LANGUAGE <Name>]\n\n"
  119.                                 "     Window = Output window specifier\n"
  120.                                 "  PubScreen = Name of public screen to open window upon\n"
  121.                                 "    Startup = ARexx script file to run on startup\n"
  122.                                 "   Settings = Main configuration file name or path name to search for it\n"
  123.                                 "       Unit = Serial device driver unit number\n"
  124.                                 "     Device = Serial device driver name\n"
  125.                                 "        New = Spawn a new `term' process\n"
  126.                                 "       Sync = Keep links to Shell environment\n"
  127.                                 "      Quiet = Start iconified\n"
  128.                                 "     Behind = Open screen behind all other screens, don't activate the window\n\n"
  129.                                 "   Language = Language to use for the user interface\n\n";
  130.  
  131.                     /* Parse the args (if any). */
  132.  
  133.                 if(ReadArgs(ARGTEMPLATE,(LONG *)ArgArray,ArgsPtr))
  134.                 {
  135.                         /* Pop a running `term' to the front? */
  136.  
  137.                     if((TermPort = (struct TermPort *)FindPort("term Port")) && !ArgArray[ARG_NEW])
  138.                     {
  139.                         if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  140.                         {
  141.                             if(TermPort -> TopWindow)
  142.                                 BumpWindow(TermPort -> TopWindow);
  143.                         }
  144.  
  145.                         TermPort = NULL;
  146.  
  147.                         FreeArgs(ArgsPtr);
  148.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  149.                         FreeVec(ArgArray);
  150.  
  151.                         CloseLibs();
  152.  
  153.                         return(RETURN_OK);
  154.                     }
  155.  
  156.                     if(ArgArray[ARG_DEBUG])
  157.                         DebugFlag = TRUE;
  158.  
  159.                         /* Special language requested? */
  160.  
  161.                     if(ArgArray[ARG_LANGUAGE])
  162.                         strcpy(Language,ArgArray[ARG_LANGUAGE]);
  163.  
  164.                         /* Are we to use a special settings path? */
  165.  
  166.                     if(ArgArray[ARG_SETTINGS])
  167.                     {
  168.                         ConfigPath = ThePath;
  169.  
  170.                         strcpy(ThePath,ArgArray[ARG_SETTINGS]);
  171.                     }
  172.  
  173.                         /* Are we to use a special ARexx host port name? */
  174.  
  175.                     if(ArgArray[ARG_PORTNAME])
  176.                         strcpy(RexxPortName,ArgArray[ARG_PORTNAME]);
  177.  
  178.                         /* Are we to use a special output window name? */
  179.  
  180.                     if(ArgArray[ARG_WINDOW])
  181.                         strcpy(WindowName,ArgArray[ARG_WINDOW]);
  182.  
  183.                         /* Are we to run an ARexx script on startup? */
  184.  
  185.                     if(ArgArray[ARG_STARTUP])
  186.                         strcpy(StartupFile,ArgArray[ARG_STARTUP]);
  187.  
  188.                         /* Are we to open a window on a public screen? */
  189.  
  190.                     if(ArgArray[ARG_PUBSCREEN])
  191.                         strcpy(SomePubScreenName,ArgArray[ARG_PUBSCREEN]);
  192.  
  193.                         /* Are we to use a special device? */
  194.  
  195.                     if(ArgArray[ARG_DEVICE])
  196.                     {
  197.                         strcpy(NewDevice,ArgArray[ARG_DEVICE]);
  198.  
  199.                         UseNewDevice = TRUE;
  200.                     }
  201.  
  202.                         /* Are we to use a special unit number? */
  203.  
  204.                     if(ArgArray[ARG_UNIT])
  205.                     {
  206.                         NewUnit = *(LONG *)ArgArray[ARG_UNIT];
  207.  
  208.                         UseNewUnit = TRUE;
  209.                     }
  210.  
  211.                         /* Are we to start up iconified? */
  212.  
  213.                     if(ArgArray[ARG_QUIET])
  214.                     {
  215.                         if(!StartupFile[0])
  216.                             DoIconify = TRUE;
  217.                     }
  218.  
  219.                         /* Hide the screen and don't activate the window? */
  220.  
  221.                     if(ArgArray[ARG_BEHIND])
  222.                         KeepQuiet = TRUE;
  223.  
  224.                         /* We are to keep our links to
  225.                          * the Shell.
  226.                          */
  227.  
  228.                     if(ArgArray[ARG_SYNC] || !ThisProcess -> pr_HomeDir)
  229.                     {
  230.                         BYTE OldPri = ThisProcess -> pr_Task . tc_Node . ln_Pri;
  231.  
  232.                             /* Open our resources and
  233.                              * squeak on failure.
  234.                              */
  235.  
  236.                         if(Result = OpenAll(ConfigPath))
  237.                         {
  238.                             if(Result[0])
  239.                                 Printf("\33[1mterm:\33[0m %s!\a\n",Result);
  240.  
  241.                             FreeArgs(ArgsPtr);
  242.                             FreeDosObject(DOS_RDARGS,ArgsPtr);
  243.                             FreeVec(ArgArray);
  244.  
  245.                             CloseAll(TRUE);
  246.  
  247.                             return(RETURN_FAIL);
  248.                         }
  249.  
  250.                             /* Go into main input
  251.                              * loop.
  252.                              */
  253.  
  254.                         if(StackSize(NULL) < 16384)
  255.                         {
  256.                             LONG Success;
  257.  
  258.                             StackCall(&Success,16384,0,(LONG (* __stdargs)())HandleInput);
  259.                         }
  260.                         else
  261.                             HandleInput();
  262.  
  263.                             /* Free the argument
  264.                              * data.
  265.                              */
  266.  
  267.                         FreeArgs(ArgsPtr);
  268.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  269.                         FreeVec(ArgArray);
  270.  
  271.                             /* Restore old priority. */
  272.  
  273.                         SetTaskPri(ThisProcess,(LONG)OldPri);
  274.  
  275.                             /* Terminate execution. */
  276.  
  277.                         CloseAll(TRUE);
  278.  
  279.                         return(RETURN_OK);
  280.                     }
  281.  
  282.                     FreeArgs(ArgsPtr);
  283.                 }
  284.                 else
  285.                 {
  286.                     PrintFault(IoErr(),"term");
  287.  
  288.                     FreeDosObject(DOS_RDARGS,ArgsPtr);
  289.                     FreeVec(ArgArray);
  290.  
  291.                     CloseLibs();
  292.  
  293.                     return(RETURN_ERROR);
  294.                 }
  295.  
  296.                 FreeDosObject(DOS_RDARGS,ArgsPtr);
  297.             }
  298.  
  299.             FreeVec(ArgArray);
  300.  
  301.                 /* Create a new process from our code. */
  302.  
  303.             if(!SegmentSplit("term main process",0,16384,HandleInput))
  304.             {
  305.                 Printf("\33[1mterm:\33[0m Failed to create new process!\a\n");
  306.  
  307.                 CloseLibs();
  308.  
  309.                 return(RETURN_FAIL);
  310.             }
  311.         }
  312.         else
  313.         {
  314.             Printf("\33[1mterm:\33[0m Failed to allocate argument vectors!\a\n");
  315.  
  316.             CloseLibs();
  317.  
  318.             return(RETURN_FAIL);
  319.         }
  320.     }
  321.     else
  322.     {
  323.             /* Try to create a local CLI structure so
  324.              * Shell commands will receive a valid
  325.              * search path list.
  326.              */
  327.  
  328.         if(LocalCLI = CloneCLI(&WBenchMsg -> sm_Message))
  329.         {
  330.             OldCLI = ThisProcess -> pr_CLI;
  331.  
  332.             ThisProcess -> pr_CLI = MKBADDR(LocalCLI);
  333.         }
  334.  
  335.         WBenchLock = CurrentDir(WBenchMsg -> sm_ArgList -> wa_Lock);
  336.  
  337.             /* Open icon.library, we want to take a
  338.              * look at the icon.
  339.              */
  340.  
  341.         if(IconBase = OpenLibrary("icon.library",0))
  342.         {
  343.             struct DiskObject *Icon;
  344.  
  345.                 /* Try to read the icon file. */
  346.  
  347.             if(Icon = GetProgramIcon())
  348.             {
  349.                 STRPTR Type;
  350.  
  351.                 if(FindToolType(Icon -> do_ToolTypes,"DEBUG"))
  352.                     DebugFlag = TRUE;
  353.  
  354.                     /* Look for a `Language' tooltype. */
  355.  
  356.                 if(Type = FindToolType(Icon -> do_ToolTypes,"LANGUAGE"))
  357.                     strcpy(Language,Type);
  358.  
  359.                     /* Look for a `Settings' tooltype. */
  360.  
  361.                 if(ConfigPath = FindToolType(Icon -> do_ToolTypes,"SETTINGS"))
  362.                 {
  363.                         /* Remember the path and continue. */
  364.  
  365.                     strcpy(ThePath,ConfigPath);
  366.  
  367.                     ConfigPath = ThePath;
  368.                 }
  369.  
  370.                     /* Look for a `Portname' tooltype. */
  371.  
  372.                 if(Type = FindToolType(Icon -> do_ToolTypes,"PORTNAME"))
  373.                     strcpy(RexxPortName,Type);
  374.                 else
  375.                     RexxPortName[0] = 0;
  376.  
  377.                     /* Look for a `Window' tooltype. */
  378.  
  379.                 if(Type = FindToolType(Icon -> do_ToolTypes,"WINDOW"))
  380.                     strcpy(WindowName,Type);
  381.                 else
  382.                     WindowName[0] = 0;
  383.  
  384.                     /* Look for a `Pubscreen' tooltype. */
  385.  
  386.                 if(Type = FindToolType(Icon -> do_ToolTypes,"PUBSCREEN"))
  387.                     strcpy(SomePubScreenName,Type);
  388.                 else
  389.                     SomePubScreenName[0] = 0;
  390.  
  391.                     /* Look for a `Startup' tooltype. */
  392.  
  393.                 if(Type = FindToolType(Icon -> do_ToolTypes,"STARTUP"))
  394.                     strcpy(StartupFile,Type);
  395.                 else
  396.                     StartupFile[0] = 0;
  397.  
  398.                     /* Look for a `Device' tooltype. */
  399.  
  400.                 if(Type = FindToolType(Icon -> do_ToolTypes,"DEVICE"))
  401.                 {
  402.                     if(Type[0])
  403.                     {
  404.                         strcpy(NewDevice,Type);
  405.  
  406.                         UseNewDevice = TRUE;
  407.                     }
  408.                 }
  409.  
  410.                     /* Look for a `Unit' tooltype. */
  411.  
  412.                 if(Type = FindToolType(Icon -> do_ToolTypes,"UNIT"))
  413.                 {
  414.                     if(Type[0])
  415.                     {
  416.                         NewUnit = Atol(Type);
  417.  
  418.                         UseNewUnit = TRUE;
  419.                     }
  420.                 }
  421.  
  422.                     /* Look for a `Quiet' tooltype. */
  423.  
  424.                 if(FindToolType(Icon -> do_ToolTypes,"QUIET"))
  425.                 {
  426.                     if(!StartupFile[0])
  427.                         DoIconify = TRUE;
  428.                 }
  429.  
  430.                     /* Look for a `Behind' tooltype. */
  431.  
  432.                 if(FindToolType(Icon -> do_ToolTypes,"BEHIND"))
  433.                     KeepQuiet = TRUE;
  434.  
  435.                     /* Free the icon. */
  436.  
  437.                 FreeDiskObject(Icon);
  438.             }
  439.  
  440.             CloseLibrary(IconBase);
  441.  
  442.             IconBase = NULL;
  443.         }
  444.  
  445.             /* Initialize this, so OpenAll will work with
  446.              * correct data.
  447.              */
  448.  
  449.         TermPort = (struct TermPort *)FindPort("term Port");
  450.  
  451.             /* We were called from Workbench. */
  452.  
  453.         if(Result = OpenAll(ConfigPath))
  454.         {
  455.             if(IntuitionBase && Result[0])
  456.                 MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  457.  
  458.             CloseAll(TRUE);
  459.         }
  460.         else
  461.         {
  462.             if(StackSize(NULL) < 16384)
  463.             {
  464.                 LONG Success;
  465.  
  466.                 StackCall(&Success,16384,0,(LONG (* __stdargs)())HandleInput);
  467.             }
  468.             else
  469.                 HandleInput();
  470.         }
  471.     }
  472.  
  473.     return(RETURN_OK);
  474. }
  475.  
  476.     /* CloseLibs():
  477.      *
  478.      *    Plain and simple: close two libraries and clean up.
  479.      */
  480.  
  481. STATIC VOID
  482. CloseLibs(VOID)
  483. {
  484.     if(UtilityBase)
  485.     {
  486.         CloseLibrary(UtilityBase);
  487.  
  488.         UtilityBase = NULL;
  489.     }
  490.  
  491.     if(WBenchMsg)
  492.         CurrentDir(WBenchLock);
  493.  
  494.     if(DOSBase)
  495.     {
  496.         CloseLibrary(DOSBase);
  497.  
  498.         DOSBase = NULL;
  499.     }
  500.  
  501.     if(WBenchMsg)
  502.     {
  503.         Forbid();
  504.  
  505.         ReplyMsg((struct Message *)WBenchMsg);
  506.     }
  507. }
  508.  
  509.     /* ProcessCleanup(register __d1 BPTR SegList):
  510.      *
  511.      *    Frees all resource the main process has allocated when
  512.      *    it exits.
  513.      */
  514.  
  515. STATIC VOID __saveds __asm
  516. ProcessCleanup(register __d1 BPTR SegList)
  517. {
  518.     CloseAll(FALSE);
  519.  
  520.     Forbid();
  521.  
  522.     UnLoadSeg(SegList);
  523.  
  524.     CloseLibrary(DOSBase);
  525.  
  526.     DOSBase = NULL;
  527. }
  528.  
  529.     /* SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function):
  530.      *
  531.      *    Create a new process from the current one.
  532.      */
  533.  
  534. STATIC struct Process * __regargs
  535. SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function)
  536. {
  537.     struct Process            *Child;
  538.     struct CommandLineInterface    *CLI;
  539.  
  540.     CLI = (struct CommandLineInterface *)BADDR(((struct Process *)SysBase -> ThisTask) -> pr_CLI);
  541.  
  542.     Forbid();
  543.  
  544.     Child = CreateNewProcTags(
  545.         NP_CommandName,    "term",
  546.         NP_Name,    Name,
  547.         NP_Priority,    Pri,
  548.         NP_StackSize,    StackSize,
  549.         NP_Entry,    Function,
  550.         NP_Cli,        TRUE,
  551.         NP_ExitCode,    ProcessCleanup,
  552.         NP_ExitData,    CLI -> cli_Module,
  553.     TAG_DONE);
  554.  
  555.     if(Child)
  556.         CLI -> cli_Module = NULL;
  557.  
  558.     Permit();
  559.  
  560.     return(Child);
  561. }
  562.  
  563.     /* HandleInput():
  564.      *
  565.      *    This is our main input loop (check window & serial).
  566.      */
  567.  
  568. VOID __saveds
  569. HandleInput()
  570. {
  571.     STRPTR    Error;
  572.     BOOLEAN    AlmostFinished = FALSE;
  573.  
  574.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  575.  
  576.         /* Open the resources we need. */
  577.  
  578.     if(!IntuitionBase)
  579.     {
  580.         STRPTR Result;
  581.  
  582.         if(Result = OpenAll(ConfigPath))
  583.         {
  584.             if(IntuitionBase && Result[0])
  585.                 MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  586.  
  587.             if(WBenchMsg)
  588.                 CloseAll(TRUE);
  589.  
  590.             return;
  591.         }
  592.     }
  593.  
  594.         /* Tell the user what he probably doesn't know yet. */
  595.  
  596.     if(TermVersion > Config -> SerialConfig -> LastVersionSaved || (TermVersion == Config -> SerialConfig -> LastVersionSaved && TermRevision > Config -> SerialConfig -> LastRevisionSaved))
  597.     {
  598.         BlockWindows();
  599.  
  600.         ScreenToFront(Window -> WScreen);
  601.  
  602.         DisplayBeep(Window -> WScreen);
  603.         DisplayBeep(Window -> WScreen);
  604.  
  605.         ShowInfo(Window,LocaleString(MSG_ATTENTION_PLEASE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_REMINDER_TXT));
  606.  
  607.         ReleaseWindows();
  608.     }
  609.  
  610.         /* Give a hint. */
  611.  
  612.     if(Config -> MiscConfig -> ProtectiveMode && !FirstInvocation)
  613.     {
  614.         BlockWindows();
  615.  
  616.         if(Config -> SerialConfig -> BaudRate >= 4800 && Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE)
  617.         {
  618.             ScreenToFront(Window -> WScreen);
  619.  
  620.             if(MyEasyRequest(Window,LocaleString(MSG_NO_RTSCTS_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Config -> SerialConfig -> BaudRate))
  621.             {
  622.                 SaveConfig(Config,PrivateConfig);
  623.  
  624.                 Config -> SerialConfig -> HandshakingProtocol = HANDSHAKING_RTSCTS_DSR;
  625.  
  626.                 ConfigSetup();
  627.             }
  628.         }
  629.  
  630.         if(Config -> SerialConfig -> BaudRate >= 4800 && Config -> ModemConfig -> ConnectAutoBaud)
  631.         {
  632.             ScreenToFront(Window -> WScreen);
  633.  
  634.             if(MyEasyRequest(Window,LocaleString(MSG_AUTOBAUD_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  635.             {
  636.                 SaveConfig(Config,PrivateConfig);
  637.  
  638.                 Config -> ModemConfig -> ConnectAutoBaud = FALSE;
  639.  
  640.                 ConfigSetup();
  641.             }
  642.         }
  643.  
  644.         ReleaseWindows();
  645.     }
  646.  
  647.         // Don't confuse the user yet, do it later ;-)
  648.  
  649.     FirstInvocation = FALSE;
  650.  
  651.         /* Start the online timer if a carrier is present? */
  652.  
  653.     if(Config -> SerialConfig -> CheckCarrier)
  654.     {
  655.             /* Is the carrier signal present? */
  656.  
  657.         if(!(GetSerialStatus() & CIAF_COMCD))
  658.         {
  659.                 /* Go into online state. */
  660.  
  661.             ObtainSemaphore(&OnlineSemaphore);
  662.  
  663.             WasOnline        = FALSE;
  664.             Online            = TRUE;
  665.  
  666.             ReleaseSemaphore(&OnlineSemaphore);
  667.  
  668.             BaudCount        = 0;
  669.             BaudBuffer[0]        = 0;
  670.             BaudPending        = FALSE;
  671.  
  672.             CurrentPay        = 0;
  673.  
  674.             ObtainSemaphore(&PatternSemaphore);
  675.  
  676.             ChosenEntry        = NULL;
  677.             ChosenPattern        = NULL;
  678.  
  679.             ReleaseSemaphore(&PatternSemaphore);
  680.  
  681.             Password[0]        = 0;
  682.             UserName[0]        = 0;
  683.  
  684.             SendStartup        = FALSE;
  685.  
  686.             LimitCount        = -1;
  687.  
  688.             CurrentBBSName[0]    = 0;
  689.             CurrentBBSComment[0]    = 0;
  690.             CurrentBBSNumber[0]    = 0;
  691.  
  692.             SetDialMenu(FALSE);
  693.         }
  694.     }
  695.  
  696.         /* Start up iconified? */
  697.  
  698.     if(DoIconify)
  699.     {
  700.         HandleIconify();
  701.  
  702.         DoIconify = FALSE;
  703.  
  704.         if(MainTerminated)
  705.             goto Stop;
  706.     }
  707.  
  708.     if(!KeepQuiet)
  709.         BumpWindow(Window);
  710.  
  711.         /* Set up the public screen data. */
  712.  
  713.     PubScreenStuff();
  714.  
  715.         /* Change program priority. */
  716.  
  717.     SetTaskPri(ThisProcess,(LONG)Config -> MiscConfig -> Priority);
  718.  
  719.     BlockWindows();
  720.  
  721.         /* Load the phone book. */
  722.  
  723.     LoadPhonebook(LastPhone);
  724.  
  725.         /* Build new menu strip. */
  726.  
  727.     if(Error = BuildMenu())
  728.     {
  729.         if(IntuitionBase)
  730.             MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
  731.  
  732.         CloseAll(TRUE);
  733.  
  734.         return;
  735.     }
  736.     else
  737.     {
  738.         if(Online)
  739.             SetDialMenu(FALSE);
  740.     }
  741.  
  742.         /* Show our business card. */
  743.  
  744.     if(!StartupFile[0] && !Config -> CommandConfig -> StartupMacro[0] && !KeepQuiet)
  745.     {
  746.         if(ShowAbout(TRUE))
  747.             while(HandleRexx());
  748.     }
  749.  
  750.     ReleaseWindows();
  751.  
  752.         /* Don't do anything silly. */
  753.  
  754.     KeepQuiet = FALSE;
  755.  
  756.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_STARTED_TXT),TermName,TermDate);
  757.  
  758.         /* Initialize the modem. */
  759.  
  760.     SerialCommand(Config -> ModemConfig -> ModemInit);
  761.  
  762.         /* Execute the startup macro (if any). */
  763.  
  764.     if(Config -> CommandConfig -> StartupMacro[0])
  765.         SerialCommand(Config -> CommandConfig -> StartupMacro);
  766.  
  767.     /*
  768.     {
  769.         STRPTR Warning =
  770.             "\f  Just to make sure you know what you are using:\r\n"
  771.             "\r\n"
  772.             "     \033#6This really is a\r\n"
  773.             "        \033[5m\033#3BETA TEST\r\n"
  774.             "        \033#4BETA TEST\033[0m\r\n"
  775.             "         \033#6release!\r\n"
  776.             "\033#5\r\n"
  777.             "                   \033[4mDISCLAIMER:\033[0m\r\n"
  778.             "\r\n"
  779.             "This  product  is  meant  for educational purposes\r\n"
  780.             "only.   If   condition   persists,   consult  your\r\n"
  781.             "physician.  Edited  for  television. See label for\r\n"
  782.             "sequence.  Avoid  contact  with  skin. No purchase\r\n"
  783.             "necessary.  Use  only in well-ventilated area. Not\r\n"
  784.             "recommended  for  children.  No  anchovies  unless\r\n"
  785.             "otherwise  specified.  Driver does not carry cash.\r\n"
  786.             "This supersedes all previous notices.\r\n";
  787.  
  788.         ConProcess(Warning,strlen(Warning));
  789.     }
  790.     */
  791.  
  792.         /* Go into input loop... */
  793.  
  794. Loop:    while(!MainTerminated)
  795.     {
  796.         if(Recording)
  797.         {
  798.             if(RecordingLine)
  799.                 Status = STATUS_RECORDING_LINE;
  800.             else
  801.                 Status = STATUS_RECORDING;
  802.         }
  803.  
  804.             /* Handle the signal responses. */
  805.  
  806.         HandleResponse();
  807.  
  808.         if(RebuildMenu)
  809.         {
  810.             if(Error = BuildMenu())
  811.             {
  812.                 if(IntuitionBase)
  813.                     MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
  814.  
  815.                 MainTerminated = TRUE;
  816.  
  817.                 break;
  818.             }
  819.  
  820.             RebuildMenu = FALSE;
  821.         }
  822.  
  823.             /* Are we to run an ARexx script file? */
  824.  
  825.         if(StartupFile[0])
  826.         {
  827.             BlockWindows();
  828.  
  829.             SendARexxCommand(StartupFile,TRUE);
  830.  
  831.             ReleaseWindows();
  832.  
  833.             StartupFile[0] = 0;
  834.         }
  835.  
  836.             /* Are we to leave the main loop? */
  837.  
  838.         if(MainTerminated)
  839.             break;
  840.  
  841.             /* Make the user notice not too obvious events. */
  842.  
  843.         if(FlowInfo . Changed)
  844.             HandleFlowChange();
  845.  
  846.             /* Are we no longer online? */
  847.  
  848.         ObtainSemaphore(&OnlineSemaphore);
  849.  
  850.         if(!Online)
  851.         {
  852.             if(WasOnline)
  853.             {
  854.                 ReleaseSemaphore(&OnlineSemaphore);
  855.  
  856.                 HandleOnlineCleanup(HungUp);
  857.  
  858.                 ObtainSemaphore(&OnlineSemaphore);
  859.  
  860.                 WasOnline = FALSE;
  861.  
  862.                 ReleaseSemaphore(&OnlineSemaphore);
  863.  
  864.                 HungUp = FALSE;
  865.             }
  866.             else
  867.                 ReleaseSemaphore(&OnlineSemaphore);
  868.         }
  869.         else
  870.             ReleaseSemaphore(&OnlineSemaphore);
  871.  
  872.             /* Now for public screen mode changes. */
  873.  
  874.         if(FixPubScreenMode)
  875.             PubScreenStuff();
  876.  
  877.             /* Now for window size changes. */
  878.  
  879.         if(FixScreenSize)
  880.             ScreenSizeStuff();
  881.  
  882.             /* Somebody told us to re-open the display
  883.              * (changed the terminal emulation/colour
  884.              * mode, etc.).
  885.              */
  886.  
  887.         if(ResetDisplay)
  888.         {
  889.             if(!DisplayReset())
  890.                 break;
  891.         }
  892.  
  893.             /* Let's see if we still have to display the
  894.              * online cost.
  895.              */
  896.  
  897.         ObtainSemaphore(&OnlineSemaphore);
  898.  
  899.         if(CurrentPay && !Online)
  900.         {
  901.             ReleaseSemaphore(&OnlineSemaphore);
  902.  
  903.                 /* Reset the text rendering styles, font, etc. in
  904.                  * order to keep the following text from getting
  905.                  * illegible.
  906.                  */
  907.  
  908.             SoftReset();
  909.  
  910.                 /* Display how much we expect
  911.                  * the user will have to pay for
  912.                  * this call.
  913.                  */
  914.  
  915.             ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  916.  
  917.             CurrentPay = 0;
  918.         }
  919.         else
  920.             ReleaseSemaphore(&OnlineSemaphore);
  921.  
  922.             /* Iconify the program? */
  923.  
  924.         if(DoIconify)
  925.         {
  926.             HandleIconify();
  927.  
  928.             if(MainTerminated)
  929.                 break;
  930.         }
  931.  
  932.             /* Reset the serial driver? */
  933.  
  934.         if(ResetSerial)
  935.         {
  936.             HandleSerialReset();
  937.  
  938.             if(MainTerminated)
  939.                 break;
  940.         }
  941.  
  942.             /* We are to release the serial.device (or
  943.              * whatever we are using) for some reason.
  944.              */
  945.  
  946.         if(ReleaseSerial)
  947.         {
  948.             HandleSerialRelease();
  949.  
  950.             if(MainTerminated)
  951.                 break;
  952.         }
  953.  
  954.             /* Invoke the dialing function? */
  955.  
  956.         if(DoDial != DIAL_IGNORE)
  957.         {
  958.             ObtainSemaphore(&OnlineSemaphore);
  959.  
  960.             if(Online)
  961.             {
  962.                 ReleaseSemaphore(&OnlineSemaphore);
  963.  
  964.                 FreeDialList(FALSE);
  965.  
  966.                 DoDial = DIAL_IGNORE;
  967.  
  968.                 Forbid();
  969.  
  970.                 if(DialMsg)
  971.                 {
  972.                     DialMsg -> rm_Result1 = RC_WARN;
  973.                     DialMsg -> rm_Result2 = 0;
  974.  
  975.                     ReplyMsg(DialMsg);
  976.  
  977.                     DialMsg = NULL;
  978.                 }
  979.  
  980.                 Permit();
  981.             }
  982.             else
  983.             {
  984.                 ReleaseSemaphore(&OnlineSemaphore);
  985.  
  986.                 if(DoDial == DIAL_LIST)
  987.                 {
  988.                     BYTE OldStatus = Status;
  989.  
  990.                     DoDial = DIAL_IGNORE;
  991.  
  992.                     BlockWindows();
  993.  
  994.                     DialPanel();
  995.  
  996.                     FreeDialList(FALSE);
  997.  
  998.                     Status = OldStatus;
  999.  
  1000.                     SetRedialMenu();
  1001.  
  1002.                     ReleaseWindows();
  1003.                 }
  1004.                 else
  1005.                 {
  1006.                     DoDial = DIAL_IGNORE;
  1007.  
  1008.                     HandleMenuCode(MEN_REDIAL,NULL);
  1009.                 }
  1010.             }
  1011.         }
  1012.  
  1013.             /* Can we quit now? */
  1014.  
  1015.         if(AlmostFinished && !CantQuit)
  1016.             break;
  1017.     }
  1018.  
  1019.         /* Don't exit until all background processes
  1020.          * have terminated.
  1021.          */
  1022.  
  1023.     if(MainTerminated && CantQuit)
  1024.     {
  1025.         MainTerminated = FALSE;
  1026.         AlmostFinished = TRUE;
  1027.  
  1028.         goto Loop;
  1029.     }
  1030.  
  1031.         /* User wants to quit term, so let's try to close
  1032.          * our magnificient screen and exit.
  1033.          */
  1034.  
  1035. Stop:    if(Screen || SharedScreen)
  1036.     {
  1037.         struct List        *PubScreenList;
  1038.         struct PubScreenNode    *ScreenNode;
  1039.         struct Screen        *WhichScreen;
  1040.  
  1041.             /* There can be only one... */
  1042.  
  1043.         if(Screen)
  1044.             WhichScreen = Screen;
  1045.         else
  1046.             WhichScreen = SharedScreen;
  1047.  
  1048.             /* Lock the list of public screens. */
  1049.  
  1050.         PubScreenList = LockPubScreenList();
  1051.  
  1052.             /* Scan the list and try to find our
  1053.              * private node.
  1054.              */
  1055.  
  1056.         for(ScreenNode = (struct PubScreenNode *)PubScreenList -> lh_Head ; ScreenNode -> psn_Node . ln_Succ ; ScreenNode = (struct PubScreenNode *)ScreenNode -> psn_Node . ln_Succ)
  1057.         {
  1058.             if(ScreenNode -> psn_Screen == WhichScreen)
  1059.                 break;
  1060.         }
  1061.  
  1062.         if(ScreenNode && ScreenNode -> psn_Node . ln_Succ)
  1063.         {
  1064.                 /* Okay, we know who and where we are,
  1065.                  * check the number of visitor windows
  1066.                  * currently open on our screen.
  1067.                  */
  1068.  
  1069.             if(ScreenNode -> psn_VisitorCount)
  1070.             {
  1071.                     /* No chance, don't close
  1072.                      * the screen now.
  1073.                      */
  1074.  
  1075.                 UnlockPubScreenList();
  1076.  
  1077.                 BlockWindows();
  1078.  
  1079.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  1080.  
  1081.                 ReleaseWindows();
  1082.  
  1083.                 AlmostFinished = MainTerminated = FALSE;
  1084.  
  1085.                 goto Loop;
  1086.             }
  1087.         }
  1088.  
  1089.         UnlockPubScreenList();
  1090.     }
  1091.  
  1092.         /* Send the modem exit command, shut down the
  1093.          * serial.device and close all resources.
  1094.          */
  1095.  
  1096.     SerialCommand(Config -> ModemConfig -> ModemExit);
  1097.  
  1098.     ClearSerial();
  1099.  
  1100.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_TERMINATED_TXT));
  1101.  
  1102.     Say(LocaleString(MSG_TERMMAIN_BYE_BYE_TXT));
  1103.  
  1104.     if(Phonebook && PhoneSize)
  1105.         DeletePhonebook(Phonebook,PhoneSize,TRUE);
  1106.  
  1107.         /* Clean up. */
  1108.  
  1109.     if(LocalCLI)
  1110.     {
  1111.         ThisProcess -> pr_CLI = OldCLI;
  1112.  
  1113.         DeleteCLI(LocalCLI);
  1114.     }
  1115.  
  1116.     if(!ThisProcess -> pr_CLI)
  1117.         CloseAll(TRUE);
  1118. }
  1119.  
  1120.     /* SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell,BOOL ConvertLF):
  1121.      *
  1122.      *    Transmit text the user typed or pasted via the
  1123.      *    clipboard.
  1124.      */
  1125.  
  1126. STATIC VOID __regargs
  1127. SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell,BOOL ConvertLF)
  1128. {
  1129.     UBYTE Mask,c;
  1130.  
  1131.     if(Config -> SerialConfig -> StripBit8)
  1132.         Mask = 0x7F;
  1133.     else
  1134.         Mask = 0xFF;
  1135.  
  1136.     while(Len--)
  1137.     {
  1138.         switch(CharType[c = (*Buffer++) & Mask])
  1139.         {
  1140.             case CHAR_ENTER:
  1141.  
  1142.                 if(Status == STATUS_HOLDING)
  1143.                 {
  1144.                     if(Bell)
  1145.                         BellSignal();
  1146.                 }
  1147.                 else
  1148.                 {
  1149.                     if(ConvertLF)
  1150.                     {
  1151.                         switch(Config -> TerminalConfig -> SendCR)
  1152.                         {
  1153.                             case EOL_LF:
  1154.  
  1155.                                 SerWrite("\n",1);
  1156.                                 break;
  1157.  
  1158.                             case EOL_CR:
  1159.  
  1160.                                 SerWrite("\r",1);
  1161.                                 break;
  1162.  
  1163.                             case EOL_LFCR:
  1164.  
  1165.                                 SerWrite("\n\r",2);
  1166.                                 break;
  1167.  
  1168.                             case EOL_CRLF:
  1169.  
  1170.                                 SerWrite("\r\n",2);
  1171.                                 break;
  1172.                         }
  1173.                     }
  1174.                     else
  1175.                     {
  1176.                         switch(Config -> TerminalConfig -> SendLF)
  1177.                         {
  1178.                             case EOL_LF:
  1179.  
  1180.                                 SerWrite("\n",1);
  1181.                                 break;
  1182.  
  1183.                             case EOL_CR:
  1184.  
  1185.                                 SerWrite("\r",1);
  1186.                                 break;
  1187.  
  1188.                             case EOL_LFCR:
  1189.  
  1190.                                 SerWrite("\n\r",2);
  1191.                                 break;
  1192.  
  1193.                             case EOL_CRLF:
  1194.  
  1195.                                 SerWrite("\r\n",2);
  1196.                                 break;
  1197.                         }
  1198.                     }
  1199.                 }
  1200.  
  1201.                 break;
  1202.  
  1203.             case CHAR_RETURN:
  1204.  
  1205.                 if(Status == STATUS_HOLDING)
  1206.                 {
  1207.                     if(Bell)
  1208.                         BellSignal();
  1209.                 }
  1210.                 else
  1211.                 {
  1212.                     switch(Config -> TerminalConfig -> SendCR)
  1213.                     {
  1214.                         case EOL_LF:
  1215.  
  1216.                             SerWrite("\n",1);
  1217.                             break;
  1218.  
  1219.                         case EOL_CR:
  1220.  
  1221.                             SerWrite("\r",1);
  1222.                             break;
  1223.  
  1224.                         case EOL_LFCR:
  1225.  
  1226.                             SerWrite("\n\r",2);
  1227.                             break;
  1228.  
  1229.                         case EOL_CRLF:
  1230.  
  1231.                             SerWrite("\r\n",2);
  1232.                             break;
  1233.                     }
  1234.                 }
  1235.  
  1236.                 break;
  1237.  
  1238.                 /* Stop in/output. */
  1239.  
  1240.             case CHAR_XON:
  1241.  
  1242.                 if(Config -> SerialConfig -> xONxOFF)
  1243.                     Status = STATUS_HOLDING;
  1244.  
  1245.                 if(Config -> SerialConfig -> PassThrough)
  1246.                     SerWrite(&c,1);
  1247.  
  1248.                 break;
  1249.  
  1250.                 /* Restart in/output. */
  1251.  
  1252.             case CHAR_XOFF:
  1253.  
  1254.                 if(Status == STATUS_HOLDING)
  1255.                     Status = STATUS_READY;
  1256.  
  1257.                 if(Config -> SerialConfig -> PassThrough)
  1258.                     SerWrite(&c,1);
  1259.  
  1260.                 break;
  1261.  
  1262.                 /* Any other character. */
  1263.  
  1264.             case CHAR_VANILLA:
  1265.  
  1266.                 if(Status == STATUS_HOLDING)
  1267.                 {
  1268.                     if(Bell)
  1269.                         BellSignal();
  1270.                 }
  1271.                 else
  1272.                 {
  1273.                     if(Config -> TerminalConfig -> FontMode == FONT_IBM)
  1274.                     {
  1275.                             /* Convert special
  1276.                              * Amiga characters into
  1277.                              * alien IBM dialect.
  1278.                              */
  1279.  
  1280.                         if(IBMConversion[c])
  1281.                             SerWrite(&IBMConversion[c],1);
  1282.                         else
  1283.                             SerWrite(&c,1);
  1284.                     }
  1285.                     else
  1286.                         SerWrite(&c,1);
  1287.                 }
  1288.  
  1289.                 break;
  1290.         }
  1291.     }
  1292. }
  1293.  
  1294.     /* HandleWindow():
  1295.      *
  1296.      *    This funny part checks the window(s) for incoming
  1297.      *    user input. Menus are handled elsewhere.
  1298.      */
  1299.  
  1300. BYTE
  1301. HandleWindow()
  1302. {
  1303.     STATIC ULONG         LastSeconds,LastMicros;
  1304.  
  1305.     struct IntuiMessage    *Message;
  1306.     ULONG             IClass,Code,Qualifier,Seconds,Micros;
  1307.     LONG             MouseX,MouseY,Len,GadgetID;
  1308.     struct Gadget        *Gadget;
  1309.     UBYTE             Char,InputBuffer[257];
  1310.     struct Window        *IDCMPWindow;
  1311.     BOOLEAN             Result = FALSE,ClickAndActivate = FALSE;
  1312.  
  1313.         /* Are we reading input from the clipboard? */
  1314.  
  1315.     if(ClipInput)
  1316.     {
  1317.         WORD Len = GetClip(InputBuffer,256,TRUE);
  1318.  
  1319.         if(Len < 0)
  1320.         {
  1321.             CloseClip();
  1322.  
  1323.             ClipInput = FALSE;
  1324.  
  1325.             if(ClipXerox)
  1326.             {
  1327.                 if(Config -> ClipConfig -> InsertSuffix[0])
  1328.                     SerialCommand(Config -> ClipConfig -> InsertSuffix);
  1329.  
  1330.                 ClipXerox = FALSE;
  1331.             }
  1332.  
  1333.             ClipPrefix = FALSE;
  1334.         }
  1335.         else
  1336.         {
  1337.             if(!ClipPrefix && ClipXerox)
  1338.             {
  1339.                 if(Config -> ClipConfig -> InsertPrefix[0])
  1340.                     SerialCommand(Config -> ClipConfig -> InsertPrefix);
  1341.  
  1342.                 ClipPrefix = TRUE;
  1343.             }
  1344.  
  1345.             if(Len > 0)
  1346.                 SendInputTextBuffer(InputBuffer,Len,FALSE,Config -> ClipConfig -> ConvertLF);
  1347.  
  1348.             Result = TRUE;
  1349.         }
  1350.     }
  1351.  
  1352.         /* Any news in the mail? */
  1353.  
  1354.     if(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  1355.     {
  1356.             /* A click into the window should activate it, but
  1357.              * we don't want to have the character snapping activated
  1358.              * under these conditions. In this case we rely upon
  1359.              * Intuition sending the IDCMP_ACTIVEWINDOW and
  1360.              * IDCMP_MOUSEBUTTONS event marked with the same
  1361.              * creation time stamp. Even if the Intuition
  1362.              * implementation should change no harm should
  1363.              * be done.
  1364.              */
  1365.  
  1366.         Seconds    = Message -> Seconds;
  1367.         Micros    = Message -> Micros;
  1368.  
  1369.         if(Seconds == LastSeconds && Micros == LastMicros && Message -> IDCMPWindow == Window)
  1370.         {
  1371.             if(Message -> Class == IDCMP_ACTIVEWINDOW || Message -> Class == IDCMP_MOUSEBUTTONS)
  1372.                 ClickAndActivate = TRUE;
  1373.         }
  1374.  
  1375.         LastSeconds    = Seconds;
  1376.         LastMicros    = Micros;
  1377.  
  1378.             /* Pick up the pieces. */
  1379.  
  1380.         IClass        = Message -> Class;
  1381.         Code        = Message -> Code;
  1382.         Qualifier    = Message -> Qualifier;
  1383.         Gadget        = (struct Gadget *)Message -> IAddress;
  1384.  
  1385.         MouseX        = Message -> MouseX;
  1386.         MouseY        = Message -> MouseY;
  1387.  
  1388.         IDCMPWindow    = Message -> IDCMPWindow;
  1389.  
  1390.         if(IClass == IDCMP_IDCMPUPDATE)
  1391.             GadgetID = GetTagData(GA_ID,0,(struct TagItem *)Gadget);
  1392.  
  1393.         if(IClass == IDCMP_RAWKEY)
  1394.         {
  1395.                 /* Perform key conversion. */
  1396.  
  1397.             if(XEmulatorBase)
  1398.             {
  1399.                 if(Len = XEmulatorUserMon(XEM_IO,InputBuffer,256,Message))
  1400.                     Char = InputBuffer[0];
  1401.             }
  1402.             else
  1403.                 Char = KeyConvert(Message,InputBuffer,&Len);
  1404.         }
  1405.  
  1406.         ReplyMsg(Message);
  1407.     }
  1408.     else
  1409.         IClass = NULL;
  1410.  
  1411.         /* Did we get any information? */
  1412.  
  1413.     if(IClass)
  1414.     {
  1415.             /* The following messages probably
  1416.              * originated from the fast! macro
  1417.              * panel.
  1418.              */
  1419.  
  1420.         if(IDCMPWindow == FastWindow)
  1421.         {
  1422.             switch(IClass)
  1423.             {
  1424.                     /* Close the window. */
  1425.  
  1426.                 case IDCMP_CLOSEWINDOW:
  1427.  
  1428.                     CloseFastWindow();
  1429.  
  1430.                     return(TRUE);
  1431.  
  1432.                     /* Window size has changed for some reason. */
  1433.  
  1434.                 case IDCMP_NEWSIZE:
  1435.  
  1436.                     RefreshFastWindow(FALSE);
  1437.  
  1438.                     return(TRUE);
  1439.  
  1440.                     /* Some gadget was invoked. */
  1441.  
  1442.                 case IDCMP_GADGETUP:
  1443.                 case IDCMP_GADGETDOWN:
  1444.  
  1445.                     GadgetID = Gadget -> GadgetID;
  1446.  
  1447.                 case IDCMP_MOUSEMOVE:
  1448.                 case IDCMP_IDCMPUPDATE:
  1449.  
  1450.                     HandleFastWindowGadget(IClass,Code,GadgetID);
  1451.  
  1452.                     return(TRUE);
  1453.             }
  1454.         }
  1455.  
  1456.             /* Status window activated? */
  1457.  
  1458.         if(IDCMPWindow == StatusWindow)
  1459.         {
  1460.             if(IClass == IDCMP_ACTIVEWINDOW && !Config -> ScreenConfig -> SplitStatus)
  1461.                 NormalCursor();
  1462.  
  1463.             if(IClass == IDCMP_CLOSEWINDOW)
  1464.             {
  1465.                 Forbid();
  1466.  
  1467.                 ClrSignal(SIG_HANDSHAKE);
  1468.  
  1469.                 Signal(StatusProcess,SIG_CLOSEWINDOW);
  1470.  
  1471.                 Wait(SIG_HANDSHAKE);
  1472.  
  1473.                 Permit();
  1474.  
  1475.                 ClearMenuStrip(StatusWindow);
  1476.                 CloseWindowSafely(StatusWindow);
  1477.  
  1478.                 StatusWindow = NULL;
  1479.             }
  1480.         }
  1481.  
  1482.             /* Main window message? */
  1483.  
  1484.         if(IDCMPWindow == Window)
  1485.         {
  1486.             switch(IClass)
  1487.             {
  1488.                 case IDCMP_INACTIVEWINDOW:
  1489.  
  1490.                     HoldClick = FALSE;
  1491.  
  1492.                     GhostCursor();
  1493.  
  1494.                     break;
  1495.  
  1496.                 case IDCMP_ACTIVEWINDOW:
  1497.  
  1498.                         // Take care of the chat gadget if necessary
  1499.  
  1500.                     ActivateChat(TRUE);
  1501.  
  1502.                     NormalCursor();
  1503.  
  1504.                     break;
  1505.  
  1506.                 case IDCMP_NEWSIZE:
  1507.  
  1508.                         /* Is a window clipping region installed? */
  1509.  
  1510.                     if(ClipRegion)
  1511.                     {
  1512.                         struct Rectangle RegionRectangle;
  1513.  
  1514.                             /* Install old region. */
  1515.  
  1516.                         InstallClipRegion(Window -> WLayer,OldRegion);
  1517.  
  1518.                             /* Fill in the clipping rectangle. */
  1519.  
  1520.                         RegionRectangle . MinX = Window -> BorderLeft;
  1521.                         RegionRectangle . MinY = Window -> BorderTop;
  1522.                         RegionRectangle . MaxX = Window -> Width - (Window -> BorderRight + 1);
  1523.                         RegionRectangle . MaxY = Window -> Height - (Window -> BorderBottom + 1);
  1524.  
  1525.                             /* Clear previous clipping region. */
  1526.  
  1527.                         ClearRegion(ClipRegion);
  1528.  
  1529.                             /* Set new clipping region. */
  1530.  
  1531.                         OrRectRegion(ClipRegion,&RegionRectangle);
  1532.  
  1533.                             /* Install new clipping region. */
  1534.  
  1535.                         OldRegion = InstallClipRegion(Window -> WLayer,ClipRegion);
  1536.                     }
  1537.  
  1538.                     ForceStatusUpdate();
  1539.  
  1540.                     HandleMenuCode(MEN_RESET_TERMINAL,Qualifier);
  1541.  
  1542.                         // Take care of the chat gadget if necessary
  1543.  
  1544.                     ActivateChat(TRUE);
  1545.  
  1546.                     TTYResize();
  1547.  
  1548.                     break;
  1549.  
  1550.                 case IDCMP_CLOSEWINDOW:
  1551.  
  1552.                     HandleMenuCode(MEN_QUIT,Qualifier);
  1553.                     break;
  1554.  
  1555.                 case IDCMP_MOUSEMOVE:
  1556.  
  1557.                     if(HoldClick)
  1558.                     {
  1559.                         if(!Marking)
  1560.                             SetMarker(ClickX,ClickY);
  1561.                         else
  1562.                         {
  1563.                             MouseX -= WindowLeft;
  1564.  
  1565.                             if(MouseX < 0)
  1566.                                 MouseX = 0;
  1567.  
  1568.                             if(MouseX > WindowWidth - 1)
  1569.                                 MouseX = WindowWidth - 1;
  1570.  
  1571.                             MouseY -= WindowTop;
  1572.  
  1573.                             if(MouseY < 0)
  1574.                                 MouseY = 0;
  1575.  
  1576.                             if(MouseY > WindowHeight - 1)
  1577.                                 MouseY = WindowHeight - 1;
  1578.  
  1579.                             MoveMarker(MouseX,MouseY);
  1580.                         }
  1581.                     }
  1582.  
  1583.                     break;
  1584.  
  1585.                 case IDCMP_MOUSEBUTTONS:
  1586.  
  1587.                     if(Code == SELECTUP)
  1588.                         ActivateChat(TRUE);
  1589.  
  1590.                     if((!ClickAndActivate || Code != SELECTDOWN) && (!XEmulatorBase || Config -> TerminalConfig -> EmulationMode != EMULATION_EXTERNAL))
  1591.                     {
  1592.                         if(Code == SELECTUP)
  1593.                             HoldClick = FALSE;
  1594.  
  1595.                         if(Code == SELECTDOWN)
  1596.                         {
  1597.                             MouseX -= WindowLeft;
  1598.  
  1599.                             if(MouseX < 0)
  1600.                                 MouseX = 0;
  1601.  
  1602.                             if(MouseX > WindowWidth - 1)
  1603.                                 MouseX = WindowWidth - 1;
  1604.  
  1605.                             MouseY -= WindowTop;
  1606.  
  1607.                             if(MouseY < 0)
  1608.                                 MouseY = 0;
  1609.  
  1610.                             if(MouseY > WindowHeight - 1)
  1611.                                 MouseY = WindowHeight - 1;
  1612.  
  1613.                             HoldClick = TRUE;
  1614.  
  1615.                             if(Qualifier & IEQUALIFIER_CONTROL)
  1616.                             {
  1617.                                 WORD FirstX,FirstY;
  1618.  
  1619.                                 FirstX = MouseX / TextFontWidth;
  1620.                                 FirstY = MouseY / TextFontHeight;
  1621.  
  1622.                                 if(FirstX <= LastColumn && FirstY <= LastLine)
  1623.                                 {
  1624.                                     UBYTE Char;
  1625.  
  1626.                                     ObtainSemaphore(RasterSemaphore);
  1627.  
  1628.                                     Char = Raster[FirstY * RasterWidth + FirstX];
  1629.  
  1630.                                     ReleaseSemaphore(RasterSemaphore);
  1631.  
  1632.                                     if(Char)
  1633.                                     {
  1634.                                         SerWrite(&Char,1);
  1635.  
  1636.                                         if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1637.                                         {
  1638.                                             switch(Config -> TerminalConfig -> SendCR)
  1639.                                             {
  1640.                                                 case EOL_LF:
  1641.  
  1642.                                                     SerWrite("\n",1);
  1643.                                                     break;
  1644.  
  1645.                                                 case EOL_CR:
  1646.  
  1647.                                                     SerWrite("\r",1);
  1648.                                                     break;
  1649.  
  1650.                                                 case EOL_LFCR:
  1651.  
  1652.                                                     SerWrite("\n\r",2);
  1653.                                                     break;
  1654.  
  1655.                                                 case EOL_CRLF:
  1656.  
  1657.                                                     SerWrite("\r\n",2);
  1658.                                                     break;
  1659.                                             }
  1660.                                         }
  1661.                                     }
  1662.                                 }
  1663.  
  1664.                                 return(TRUE);
  1665.                             }
  1666.  
  1667.                             if((Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) && (Qualifier & IEQUALIFIER_LEFTBUTTON))
  1668.                             {
  1669.                                 WORD DeltaX,DeltaY;
  1670.  
  1671.                                 ObtainSemaphore(&TerminalSemaphore);
  1672.  
  1673.                                 DeltaX = MouseX / TextFontWidth  - CursorX;
  1674.                                 DeltaY = MouseY / TextFontHeight - CursorY;
  1675.  
  1676.                                 ReleaseSemaphore(&TerminalSemaphore);
  1677.  
  1678.                                 if(DeltaX || DeltaY)
  1679.                                 {
  1680.                                     if(DeltaX > 0)
  1681.                                     {
  1682.                                         DeltaX++;
  1683.  
  1684.                                         while(DeltaX--)
  1685.                                             SerWrite("\33[C",3);
  1686.                                     }
  1687.  
  1688.                                     if(DeltaX < 0)
  1689.                                     {
  1690.                                         while(DeltaX++)
  1691.                                             SerWrite("\33[D",3);
  1692.                                     }
  1693.  
  1694.                                     if(DeltaY > 0)
  1695.                                     {
  1696.                                         DeltaY++;
  1697.  
  1698.                                         while(DeltaY--)
  1699.                                             SerWrite("\33[B",3);
  1700.                                     }
  1701.  
  1702.                                     if(DeltaY < 0)
  1703.                                     {
  1704.                                         while(DeltaY++)
  1705.                                             SerWrite("\33[A",3);
  1706.                                     }
  1707.                                 }
  1708.  
  1709.                                 return(TRUE);
  1710.                             }
  1711.  
  1712.                             ReportMouse(TRUE,Window);
  1713.  
  1714.                             if(!FirstClick)
  1715.                             {
  1716.                                 ULONG CurrentSecs,CurrentMicros;
  1717.  
  1718.                                 CurrentTime(&CurrentSecs,&CurrentMicros);
  1719.  
  1720.                                 FirstClick = TRUE;
  1721.  
  1722.                                 if(ABS(ClickX - MouseX) <= TextFontWidth && ABS(ClickY - MouseY) <= TextFontHeight && DoubleClick(ClickSecs,ClickMicros,CurrentSecs,CurrentMicros))
  1723.                                 {
  1724.                                     MarkWord(ClickX,ClickY);
  1725.  
  1726.                                     return(TRUE);
  1727.                                 }
  1728.                                 else
  1729.                                 {
  1730.                                     CurrentTime(&ClickSecs,&ClickMicros);
  1731.  
  1732.                                     FirstClick    = FALSE;
  1733.  
  1734.                                     ClickX        = MouseX;
  1735.                                     ClickY        = MouseY;
  1736.                                 }
  1737.                             }
  1738.                             else
  1739.                             {
  1740.                                 CurrentTime(&ClickSecs,&ClickMicros);
  1741.  
  1742.                                 FirstClick    = FALSE;
  1743.  
  1744.                                 ClickX        = MouseX;
  1745.                                 ClickY        = MouseY;
  1746.                             }
  1747.  
  1748.                             if(Marking)
  1749.                             {
  1750.                                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1751.                                     MoveMarker(MouseX,MouseY);
  1752.                                 else
  1753.                                 {
  1754.                                     DropMarker();
  1755.  
  1756.                                     CurrentTime(&ClickSecs,&ClickMicros);
  1757.  
  1758.                                     FirstClick    = FALSE;
  1759.  
  1760.                                     ClickX        = MouseX;
  1761.                                     ClickY        = MouseY;
  1762.  
  1763.                                     ReportMouse(TRUE,Window);
  1764.                                 }
  1765.                             }
  1766.                         }
  1767.                     }
  1768.  
  1769.                     break;
  1770.             }
  1771.         }
  1772.  
  1773.             /* Now for general information. */
  1774.  
  1775.         switch(IClass)
  1776.         {
  1777.             case IDCMP_RAWKEY:
  1778.  
  1779.                     /* Take care of the numeric keypad. */
  1780.  
  1781.                 if((Qualifier & IEQUALIFIER_NUMERICPAD) && (Config -> EmulationConfig -> NumericMode == KEYMODE_APPLICATION))
  1782.                 {
  1783.                     STATIC STRPTR StringTable[22][2] =
  1784.                     {
  1785.                         "0",    "\033Op",
  1786.                         "1",    "\033Oq",
  1787.                         "2",    "\033Or",
  1788.                         "3",    "\033Os",
  1789.                         "4",    "\033Ot",
  1790.                         "5",    "\033Ou",
  1791.                         "6",    "\033Ov",
  1792.                         "7",    "\033Ow",
  1793.                         "8",    "\033Ox",
  1794.                         "9",    "\033Oy",
  1795.                         "-",    "\033Om",
  1796.                         "+",    "\033Ol",    // This should really be a comma
  1797.                         ".",    "\033On",
  1798.  
  1799.                         "(",    "\033OP",
  1800.                         "[",    "\033OP",
  1801.                         "{",    "\033OP",
  1802.                         "]",    "\033OQ",
  1803.                         ")",    "\033OQ",
  1804.                         "}",    "\033OQ",
  1805.                         "/",    "\033OR",
  1806.                         "*",    "\033OS",
  1807.  
  1808.                         "\r",    "\033OM"
  1809.                     };
  1810.  
  1811.                     STATIC struct { UBYTE Code; STRPTR String; } CodeTable[18] =
  1812.                     {
  1813.                         0x0F,    "\033Op",    // "0"
  1814.                         0x1D,    "\033Oq",    // "1"
  1815.                         0x1E,    "\033Or",    // "2"
  1816.                         0x1F,    "\033Os",    // "3"
  1817.                         0x2D,    "\033Ot",    // "4"
  1818.                         0x2E,    "\033Ou",    // "5"
  1819.                         0x2F,    "\033Ov",    // "6"
  1820.                         0x3D,    "\033Ow",    // "7"
  1821.                         0x3E,    "\033Ox",    // "8"
  1822.                         0x3F,    "\033Oy",    // "9"
  1823.                         0x4A,    "\033Om",    // "-"
  1824.                         0x5E,    "\033Ol",    // "+", but this should really be a comma
  1825.                         0x3C,    "\033On",    // "."
  1826.  
  1827.                         0x5A,    "\033OP",    // "["
  1828.                         0x5B,    "\033OQ",    // "]"
  1829.                         0x5C,    "\033OR",    // "/"
  1830.                         0x5D,    "\033OS",    // "*"
  1831.  
  1832.                         0x43,    "\033OM"    // <cr>
  1833.                     };
  1834.  
  1835.                     STRPTR    String = NULL;
  1836.                     WORD    i;
  1837.  
  1838.                     for(i = 0 ; i < 22 ; i++)
  1839.                     {
  1840.                         if(Char == StringTable[i][0][0])
  1841.                         {
  1842.                             String = StringTable[i][1];
  1843.  
  1844.                             break;
  1845.                         }
  1846.                     }
  1847.  
  1848.                     if(!String)
  1849.                     {
  1850.                         for(i = 0 ; i < 18 ; i++)
  1851.                         {
  1852.                             if(Code == CodeTable[i] . Code)
  1853.                             {
  1854.                                 String = CodeTable[i] . String;
  1855.  
  1856.                                 break;
  1857.                             }
  1858.                         }
  1859.                     }
  1860.  
  1861.                     if(String)
  1862.                     {
  1863.                         if(ClipInput)
  1864.                         {
  1865.                             CloseClip();
  1866.  
  1867.                             ClipInput = ClipXerox = ClipPrefix = FALSE;
  1868.                         }
  1869.  
  1870.                         SerWrite(String,strlen(String));
  1871.  
  1872.                         Len = 0;
  1873.                     }
  1874.                 }
  1875.  
  1876.                     /* This looks like a raw, or better, now cooked key. */
  1877.  
  1878.                 if(Len)
  1879.                 {
  1880.                     switch(CharType[Char])
  1881.                     {
  1882.                         case CHAR_HELP:
  1883.  
  1884.                             GuideDisplay(CONTEXT_MAIN);
  1885.  
  1886.                             Len = 0;
  1887.  
  1888.                             break;
  1889.  
  1890.                         case CHAR_CURSOR:
  1891.  
  1892.                             if(ClipInput)
  1893.                             {
  1894.                                 CloseClip();
  1895.  
  1896.                                 ClipInput = ClipXerox = ClipPrefix = FALSE;
  1897.                             }
  1898.  
  1899.                                 /* If in cursor key applications mode,
  1900.                                  * send the corresponding string.
  1901.                                  */
  1902.  
  1903.                             if(Config -> EmulationConfig -> CursorMode == KEYMODE_APPLICATION)
  1904.                             {
  1905.                                 STATIC STRPTR CursorTable[4] =
  1906.                                 {
  1907.                                     "\033OA",
  1908.                                     "\033OB",
  1909.                                     "\033OC",
  1910.                                     "\033OD"
  1911.                                 };
  1912.  
  1913.                                 SerWrite(CursorTable[Char - CUP],3);
  1914.                             }
  1915.                             else
  1916.                             {
  1917.                                 WORD QualType;
  1918.  
  1919.                                     /* Find the approriate qualifier. */
  1920.  
  1921.                                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1922.                                     QualType = 1;
  1923.                                 else
  1924.                                 {
  1925.                                     if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1926.                                         QualType = 2;
  1927.                                     else
  1928.                                     {
  1929.                                         if(Qualifier & IEQUALIFIER_CONTROL)
  1930.                                             QualType = 3;
  1931.                                         else
  1932.                                             QualType = 0;
  1933.                                     }
  1934.                                 }
  1935.  
  1936.                                     /* Send the corresponding string. */
  1937.  
  1938.                                 SerialCommand(CursorKeys -> Keys[QualType][Char - CUP]);
  1939.                             }
  1940.  
  1941.                             Len = 0;
  1942.  
  1943.                             break;
  1944.  
  1945.                             /* Any function key pressed? */
  1946.  
  1947.                         case CHAR_FUNCTION:
  1948.  
  1949.                             if(ClipInput)
  1950.                             {
  1951.                                 CloseClip();
  1952.  
  1953.                                 ClipInput = ClipXerox = ClipPrefix = FALSE;
  1954.                             }
  1955.  
  1956.                             if(Qualifier & IEQUALIFIER_CONTROL)
  1957.                                 SerialCommand(MacroKeys -> Keys[3][Char - FN1]);
  1958.                             else
  1959.                             {
  1960.                                 if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1961.                                     SerialCommand(MacroKeys -> Keys[2][Char - FN1]);
  1962.                                 else
  1963.                                 {
  1964.                                     if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1965.                                         SerialCommand(MacroKeys -> Keys[1][Char - FN1]);
  1966.                                     else
  1967.                                         SerialCommand(MacroKeys -> Keys[0][Char - FN1]);
  1968.                                 }
  1969.                             }
  1970.  
  1971.                             Len = 0;
  1972.  
  1973.                             break;
  1974.  
  1975.                             /* Anything else? */
  1976.  
  1977.                         default:
  1978.  
  1979.                             if(Len == 1 && Char == '\r' && Recording && !RecordingLine && (Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  1980.                             {
  1981.                                 RememberInputText("\r",1);
  1982.  
  1983.                                 Len = 0;
  1984.  
  1985.                                 RecordingLine = TRUE;
  1986.  
  1987.                                 RememberResetInput();
  1988.  
  1989.                                 RememberOutput = FALSE;
  1990.                                 RememberInput = TRUE;
  1991.  
  1992.                                 CheckItem(MEN_RECORD_LINE,TRUE);
  1993.                             }
  1994.  
  1995.                             break;
  1996.                     }
  1997.  
  1998.                         /* Any characters to send? */
  1999.  
  2000.                     if(Len)
  2001.                         SendInputTextBuffer(InputBuffer,Len,TRUE,FALSE);
  2002.                 }
  2003.  
  2004.                 break;
  2005.  
  2006.                 /* A menu item was selected. */
  2007.  
  2008.             case IDCMP_MENUPICK:
  2009.  
  2010.                 HandleMenu(Code,Qualifier);
  2011.  
  2012.                     // Take care of the chat gadget if necessary
  2013.  
  2014.                 ActivateChat(TRUE);
  2015.  
  2016.                 break;
  2017.  
  2018.                 /* Menu help is required. */
  2019.  
  2020.             case IDCMP_MENUHELP:
  2021.  
  2022.                 if(MENUNUM(Code) == NOMENU || MENUNUM(Code) > 9 || ITEMNUM(Code) == NOITEM)
  2023.                     GuideDisplay(CONTEXT_MAIN_MENU);
  2024.                 else
  2025.                     GuideDisplay(CONTEXT_PROJECT_MEN + MENUNUM(Code));
  2026.  
  2027.                 break;
  2028.         }
  2029.  
  2030.         return(TRUE);
  2031.     }
  2032.  
  2033.     return(Result);
  2034. }
  2035.  
  2036.     /* HandleLocalDialList(BYTE ClearIt):
  2037.      *
  2038.      *    Invoke the local dialing list or clear it.
  2039.      */
  2040.  
  2041. STATIC VOID __regargs
  2042. HandleLocalDialList(BYTE ClearIt)
  2043. {
  2044.     if(Menu)
  2045.     {
  2046.         struct MenuItem *DialItem;
  2047.  
  2048.         if(DialItem = FindThisItem(Menu,FirstDialMenu))
  2049.         {
  2050.             if(Window)
  2051.                 ClearMenuStrip(Window);
  2052.  
  2053.             if(StatusWindow)
  2054.                 ClearMenuStrip(StatusWindow);
  2055.  
  2056.             if(FastWindow)
  2057.                 ClearMenuStrip(FastWindow);
  2058.  
  2059.             do
  2060.                 DialItem -> Flags &= ~CHECKED;
  2061.             while(DialItem = DialItem -> NextItem);
  2062.  
  2063.             if(Window)
  2064.                 ResetMenuStrip(Window,Menu);
  2065.  
  2066.             if(StatusWindow)
  2067.                 ResetMenuStrip(StatusWindow,Menu);
  2068.  
  2069.             if(FastWindow)
  2070.                 ResetMenuStrip(FastWindow,Menu);
  2071.         }
  2072.     }
  2073.  
  2074.     if(LocalDialList)
  2075.     {
  2076.         ObtainSemaphore(&OnlineSemaphore);
  2077.  
  2078.         if(LocalDialList -> lh_Head -> ln_Succ && !Online && !ClearIt)
  2079.         {
  2080.             ReleaseSemaphore(&OnlineSemaphore);
  2081.  
  2082.             FreeDialList(TRUE);
  2083.  
  2084.             DialList = LocalDialList;
  2085.  
  2086.             LocalDialList = NULL;
  2087.  
  2088.             LocalCount = -1;
  2089.  
  2090.             SetRedialMenu();
  2091.  
  2092.             HandleMenuCode(MEN_REDIAL,NULL);
  2093.         }
  2094.         else
  2095.         {
  2096.             ReleaseSemaphore(&OnlineSemaphore);
  2097.  
  2098.             FreeList(LocalDialList);
  2099.  
  2100.             FreeVecPooled(LocalDialList);
  2101.  
  2102.             LocalDialList = NULL;
  2103.  
  2104.             LocalCount = -1;
  2105.         }
  2106.     }
  2107. }
  2108.  
  2109.     /* HandleMenuCode(ULONG Code,ULONG Qualifier):
  2110.      *
  2111.      *    Handle each function associated with a menu code.
  2112.      */
  2113.  
  2114. VOID __regargs
  2115. HandleMenuCode(ULONG Code,ULONG Qualifier)
  2116. {
  2117.     struct FileRequester    *FileRequest;
  2118.     UBYTE             DummyBuffer[MAX_FILENAME_LENGTH],
  2119.                 *DummyChar;
  2120.     BYTE             OldStatus = Status;
  2121.  
  2122.     BPTR             SomeFile;
  2123.     APTR             OldPtr;
  2124.  
  2125.     struct MenuItem        *Item;
  2126.  
  2127.     switch(Code)
  2128.     {
  2129.             /* Save screen as IFF-ILBM file. */
  2130.  
  2131.         case MEN_SAVE_AS_PICTURE:
  2132.  
  2133.             BlockWindows();
  2134.  
  2135.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),TRUE))
  2136.             {
  2137.                 if(!SaveWindow(DummyBuffer,Window))
  2138.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  2139.  
  2140.                 FreeAslRequest(FileRequest);
  2141.             }
  2142.  
  2143.             ReleaseWindows();
  2144.  
  2145.             break;
  2146.  
  2147.             /* Save screen as ASCII file. */
  2148.  
  2149.         case MEN_SAVE_AS_TEXT:
  2150.  
  2151.             BlockWindows();
  2152.  
  2153.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  2154.             {
  2155.                 LONG Error = 0;
  2156.  
  2157.                 if(GetFileSize(DummyBuffer))
  2158.                 {
  2159.                     switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  2160.                     {
  2161.                         case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2162.                             break;
  2163.  
  2164.                         case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  2165.                             {
  2166.                                 if(Seek(SomeFile,0,OFFSET_END) == -1)
  2167.                                 {
  2168.                                     Close(SomeFile);
  2169.  
  2170.                                     SomeFile = NULL;
  2171.                                 }
  2172.                             }
  2173.  
  2174.                             break;
  2175.  
  2176.                         case 0:    SomeFile = ~0;
  2177.                             break;
  2178.                     }
  2179.                 }
  2180.                 else
  2181.                     SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2182.  
  2183.                 if(SomeFile)
  2184.                 {
  2185.                     if(SomeFile != ~0)
  2186.                     {
  2187.                         LONG     i,j;
  2188.                         UBYTE    *Buffer;
  2189.  
  2190.                         for(i = 0 ; i < RasterHeight ; i++)
  2191.                         {
  2192.                             Buffer = &Raster[i * RasterWidth];
  2193.  
  2194.                             j = LastColumn;
  2195.  
  2196.                             while(j >= 0 && Buffer[j] == ' ')
  2197.                                 j--;
  2198.  
  2199.                             if(j >= 0)
  2200.                             {
  2201.                                 SetIoErr(0);
  2202.  
  2203.                                 if(FWrite(SomeFile,Buffer,j + 1,1) < 1)
  2204.                                 {
  2205.                                     Error = IoErr();
  2206.  
  2207.                                     break;
  2208.                                 }
  2209.                             }
  2210.  
  2211.                             SetIoErr(0);
  2212.  
  2213.                             if(FWrite(SomeFile,"\n",1,1) < 1)
  2214.                             {
  2215.                                 Error = IoErr();
  2216.  
  2217.                                 break;
  2218.                             }
  2219.                         }
  2220.  
  2221.                         Close(SomeFile);
  2222.  
  2223.                         AddProtection(DummyBuffer,FIBF_EXECUTE);
  2224.  
  2225.                         if(Config -> MiscConfig -> CreateIcons)
  2226.                             AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  2227.                     }
  2228.                 }
  2229.                 else
  2230.                     Error = IoErr();
  2231.  
  2232.                 if(Error)
  2233.                     ShowError(Window,ERR_SAVE_ERROR,Error,DummyBuffer);
  2234.  
  2235.                 FreeAslRequest(FileRequest);
  2236.             }
  2237.  
  2238.             ReleaseWindows();
  2239.  
  2240.             break;
  2241.  
  2242.             /* Print the screen (pure ASCII). */
  2243.  
  2244.         case MEN_PRINT_SCREEN:
  2245.  
  2246.             BlockWindows();
  2247.  
  2248.             if(RasterEnabled)
  2249.                 PrintSomething(PRINT_SCREEN);
  2250.             else
  2251.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NO_DATA_TO_PRINT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2252.  
  2253.             ReleaseWindows();
  2254.  
  2255.             break;
  2256.  
  2257.             /* Print the screen (graphics). */
  2258.  
  2259.         case MEN_PRINT_SCREEN_AS_GFX:
  2260.  
  2261.             BlockWindows();
  2262.  
  2263.             PrintScreenGfx();
  2264.  
  2265.             ReleaseWindows();
  2266.  
  2267.             break;
  2268.  
  2269.             /* Print the clipboard contents. */
  2270.  
  2271.         case MEN_PRINT_CLIP:
  2272.  
  2273.             BlockWindows();
  2274.  
  2275.             PrintSomething(PRINT_CLIP);
  2276.  
  2277.             ReleaseWindows();
  2278.  
  2279.             break;
  2280.  
  2281.             /* Open/close the terminal capture file. */
  2282.  
  2283.         case MEN_CAPTURE_TO_FILE:
  2284.  
  2285.             if(FileCapture)
  2286.                 CloseFileCapture();
  2287.             else
  2288.                 OpenFileCapture();
  2289.  
  2290.             CheckItem(MEN_CAPTURE_TO_FILE,FileCapture != NULL);
  2291.  
  2292.             break;
  2293.  
  2294.             /* Start/terminate the printer
  2295.              * capture.
  2296.              */
  2297.  
  2298.         case MEN_CAPTURE_TO_PRINTER:
  2299.  
  2300.             if(PrinterCapture)
  2301.                 ClosePrinterCapture(TRUE);
  2302.             else
  2303.                 OpenPrinterCapture(FALSE);
  2304.  
  2305.             CheckItem(MEN_CAPTURE_TO_PRINTER,PrinterCapture != NULL);
  2306.  
  2307.             break;
  2308.  
  2309.             /* Iconify the program. */
  2310.  
  2311.         case MEN_ICONIFY:
  2312.  
  2313.             if(Config -> MiscConfig -> ProtectiveMode)
  2314.             {
  2315.                 ObtainSemaphore(&OnlineSemaphore);
  2316.  
  2317.                 if(Online && Config -> MiscConfig -> ReleaseDevice && !(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  2318.                 {
  2319.                     ReleaseSemaphore(&OnlineSemaphore);
  2320.  
  2321.                     BlockWindows();
  2322.  
  2323.                     if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2324.                     {
  2325.                         ReleaseWindows();
  2326.  
  2327.                         break;
  2328.                     }
  2329.  
  2330.                     ReleaseWindows();
  2331.                 }
  2332.                 else
  2333.                     ReleaseSemaphore(&OnlineSemaphore);
  2334.             }
  2335.  
  2336.             DoIconify = TRUE;
  2337.  
  2338.             break;
  2339.  
  2340.             /* Say who we are. */
  2341.  
  2342.         case MEN_ABOUT:
  2343.  
  2344.             BlockWindows();
  2345. #ifdef DATAFEED
  2346.             if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2347.             {
  2348.                 STATIC UBYTE LastFile[40],LastPath[256];
  2349.  
  2350.                 extern BPTR DataFeed;
  2351.  
  2352.                 if(DataFeed)
  2353.                 {
  2354.                     Close(DataFeed);
  2355.  
  2356.                     DataFeed = NULL;
  2357.                 }
  2358.  
  2359.                 if(FileRequest = GetFile(Window,"Select terminal test file",LastPath,LastFile,DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SELECT_TXT),FALSE))
  2360.                 {
  2361.                     if(GetFileSize(DummyBuffer))
  2362.                     {
  2363.                         if(DataFeed = Open(DummyBuffer,MODE_OLDFILE))
  2364.                         {
  2365.                             strcpy(LastFile,FileRequest -> fr_File);
  2366.                             strcpy(LastPath,FileRequest -> fr_Drawer);
  2367.  
  2368.                             if(Kick30)
  2369.                                 SetVBuf(DataFeed,NULL,2,8192);
  2370.                         }
  2371.                     }
  2372.  
  2373.                     FreeAslRequest(FileRequest);
  2374.                 }
  2375.             }
  2376.             else
  2377. #endif    /* DATAFEED */
  2378.  
  2379.             ShowAbout(FALSE);
  2380.  
  2381.             ReleaseWindows();
  2382.  
  2383.             break;
  2384.  
  2385.             /* Terminate the program. */
  2386.  
  2387.         case MEN_QUIT:
  2388.  
  2389.             if((Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) || !Config -> MiscConfig -> ProtectiveMode)
  2390.                 MainTerminated = TRUE;
  2391.             else
  2392.             {
  2393.                 STRPTR    Buffer;
  2394.                 LONG    OldLen,Len = strlen(LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT)) + 3;
  2395.  
  2396.                 OldLen = Len;
  2397.  
  2398.                 ObtainSemaphore(&OnlineSemaphore);
  2399.  
  2400.                 if(Online)
  2401.                     Len += strlen(LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT)) + 4;
  2402.  
  2403.                 ReleaseSemaphore(&OnlineSemaphore);
  2404.  
  2405.                 if(BufferChanged)
  2406.                     Len += strlen(LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT)) + 4;
  2407.  
  2408.                 if(ConfigChanged)
  2409.                     Len += strlen(LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT)) + 4;
  2410.  
  2411.                 if(PhonebookChanged)
  2412.                     Len += strlen(LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT)) + 4;
  2413.  
  2414.                 if(TranslationChanged)
  2415.                     Len += strlen(LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT)) + 4;
  2416.  
  2417.                 if(MacroChanged)
  2418.                     Len += strlen(LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT)) + 4;
  2419.  
  2420.                 if(CursorKeysChanged)
  2421.                     Len += strlen(LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT)) + 4;
  2422.  
  2423.                 if(FastMacrosChanged)
  2424.                     Len += strlen(LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT)) + 4;
  2425.  
  2426.                 if(HotkeysChanged)
  2427.                     Len += strlen(LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT)) + 4;
  2428.  
  2429.                 if(SpeechChanged)
  2430.                     Len += strlen(LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT)) + 4;
  2431.  
  2432.                 if(SoundChanged)
  2433.                     Len += strlen(LocaleString(MSG_WAIT_SOUND_SETTINGS_CHANGED_TXT)) + 4;
  2434.  
  2435.                 BlockWindows();
  2436.  
  2437.                 OldPtr = ThisProcess -> pr_WindowPtr;
  2438.  
  2439.                 ThisProcess -> pr_WindowPtr = (APTR)Window;
  2440.  
  2441.                 if(OldLen != Len)
  2442.                 {
  2443.                     if(Buffer = (STRPTR)AllocVecPooled(Len,MEMF_ANY))
  2444.                     {
  2445.                         SPrintf(Buffer,"%s\n\n",LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT));
  2446.  
  2447.                         ObtainSemaphore(&OnlineSemaphore);
  2448.  
  2449.                         if(Online)
  2450.                         {
  2451.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT));
  2452.  
  2453.                             strcat(Buffer,SharedBuffer);
  2454.                         }
  2455.  
  2456.                         ReleaseSemaphore(&OnlineSemaphore);
  2457.  
  2458.                         if(BufferChanged)
  2459.                         {
  2460.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT));
  2461.  
  2462.                             strcat(Buffer,SharedBuffer);
  2463.                         }
  2464.  
  2465.                         if(ConfigChanged)
  2466.                         {
  2467.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT));
  2468.  
  2469.                             strcat(Buffer,SharedBuffer);
  2470.                         }
  2471.  
  2472.                         if(PhonebookChanged)
  2473.                         {
  2474.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT));
  2475.  
  2476.                             strcat(Buffer,SharedBuffer);
  2477.                         }
  2478.  
  2479.                         if(TranslationChanged)
  2480.                         {
  2481.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT));
  2482.  
  2483.                             strcat(Buffer,SharedBuffer);
  2484.                         }
  2485.  
  2486.                         if(MacroChanged)
  2487.                         {
  2488.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT));
  2489.  
  2490.                             strcat(Buffer,SharedBuffer);
  2491.                         }
  2492.  
  2493.                         if(CursorKeysChanged)
  2494.                         {
  2495.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT));
  2496.  
  2497.                             strcat(Buffer,SharedBuffer);
  2498.                         }
  2499.  
  2500.                         if(FastMacrosChanged)
  2501.                         {
  2502.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT));
  2503.  
  2504.                             strcat(Buffer,SharedBuffer);
  2505.                         }
  2506.  
  2507.                         if(HotkeysChanged)
  2508.                         {
  2509.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT));
  2510.  
  2511.                             strcat(Buffer,SharedBuffer);
  2512.                         }
  2513.  
  2514.                         if(SpeechChanged)
  2515.                         {
  2516.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT));
  2517.  
  2518.                             strcat(Buffer,SharedBuffer);
  2519.                         }
  2520.  
  2521.                         if(MyEasyRequest(Window,Buffer,LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2522.                             MainTerminated = TRUE;
  2523.  
  2524.                         FreeVecPooled(Buffer);
  2525.                     }
  2526.                     else
  2527.                         MainTerminated = TRUE;
  2528.                 }
  2529.                 else
  2530.                     MainTerminated = TRUE;
  2531.  
  2532.                 ThisProcess -> pr_WindowPtr = OldPtr;
  2533.  
  2534.                 ReleaseWindows();
  2535.             }
  2536.  
  2537.             break;
  2538.  
  2539.             /* Feed the contents of the clipboard
  2540.              * into the input stream.
  2541.              */
  2542.  
  2543.         case MEN_PASTE:
  2544.  
  2545.             if(!OpenClip(Config -> ClipConfig -> ClipboardUnit))
  2546.             {
  2547.                 ClipInput = TRUE;
  2548.  
  2549.                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2550.                     ClipXerox = TRUE;
  2551.             }
  2552.             else
  2553.                 ClipInput = FALSE;
  2554.  
  2555.             break;
  2556.  
  2557.         case MEN_COPY:
  2558.  
  2559.             if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2560.                 ClipMarker(TRUE);
  2561.             else
  2562.                 ClipMarker(FALSE);
  2563.  
  2564.             break;
  2565.  
  2566.         case MEN_CLEAR:
  2567.  
  2568.             DropMarker();
  2569.             break;
  2570.  
  2571.             /* Execute an AmigaDOS command. */
  2572.  
  2573.         case MEN_EXECUTE_DOS_COMMAND:
  2574.  
  2575.             BlockWindows();
  2576.  
  2577.                 /* Enter the name of the command. */
  2578.  
  2579.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AMIGADOS_COMMAND_TXT),AmigaDOSCommandBuffer))
  2580.                 SendAmigaDOSCommand(AmigaDOSCommandBuffer);
  2581.  
  2582.             ReleaseWindows();
  2583.  
  2584.             break;
  2585.  
  2586.             /* Execute an ARexx script command. */
  2587.  
  2588.         case MEN_EXECUTE_REXX_COMMAND:
  2589.  
  2590.             BlockWindows();
  2591.  
  2592.                 /* Get the rexx file name/program. */
  2593.  
  2594.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AREXX_COMMAND_TXT),ARexxCommandBuffer))
  2595.                 SendARexxCommand(ARexxCommandBuffer,TRUE);
  2596.  
  2597.             ReleaseWindows();
  2598.  
  2599.             break;
  2600.  
  2601.             /* Turn recording on/off. */
  2602.  
  2603.         case MEN_RECORD:
  2604.  
  2605.             if(GetItem(MEN_RECORD))
  2606.             {
  2607.                 if(!Recording)
  2608.                 {
  2609.                     if(CreateRecord(CurrentBBSName[0] ? CurrentBBSName : LocaleString(MSG_SCREENPANEL_UNKNOWN_TXT)))
  2610.                     {
  2611.                         RememberResetOutput();
  2612.                         RememberResetInput();
  2613.  
  2614.                         RememberOutput = TRUE;
  2615.  
  2616.                         Recording = TRUE;
  2617.                         RecordingLine = FALSE;
  2618.  
  2619.                         OnItem(MEN_RECORD_LINE);
  2620.                     }
  2621.                 }
  2622.             }
  2623.             else
  2624.             {
  2625.                 if(Recording)
  2626.                 {
  2627.                     FinishRecord();
  2628.  
  2629.                     RememberOutput = FALSE;
  2630.                     RememberInput = FALSE;
  2631.  
  2632.                     Recording = FALSE;
  2633.                     RecordingLine = FALSE;
  2634.  
  2635.                     OffItem(MEN_RECORD_LINE);
  2636.  
  2637.                     Status = STATUS_READY;
  2638.                 }
  2639.             }
  2640.  
  2641.             break;
  2642.  
  2643.         case MEN_RECORD_LINE:
  2644.  
  2645.             if(Recording)
  2646.             {
  2647.                 if(GetItem(MEN_RECORD))
  2648.                 {
  2649.                     if(!RecordingLine)
  2650.                     {
  2651.                         RecordingLine = TRUE;
  2652.  
  2653.                         RememberResetInput();
  2654.  
  2655.                         RememberOutput = FALSE;
  2656.                         RememberInput = TRUE;
  2657.                     }
  2658.                 }
  2659.                 else
  2660.                 {
  2661.                     if(RecordingLine)
  2662.                     {
  2663.                         RememberSpill();
  2664.  
  2665.                         RecordingLine = FALSE;
  2666.  
  2667.                         RememberOutput = TRUE;
  2668.                         RememberInput = FALSE;
  2669.                     }
  2670.                 }
  2671.             }
  2672.  
  2673.             break;
  2674.  
  2675.         case MEN_DISABLE_TRAPS:
  2676.  
  2677.             if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
  2678.             {
  2679.                 ObtainSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
  2680.  
  2681.                 if(!(Item -> Flags & CHECKED) && GenericListTable[GLIST_TRAP] -> ListHeader . mlh_Head -> mln_Succ)
  2682.                     WatchTraps = TRUE;
  2683.                 else
  2684.                     WatchTraps = FALSE;
  2685.  
  2686.                 ReleaseSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
  2687.             }
  2688.  
  2689.             break;
  2690.  
  2691.             /* Edit the trap settings? */
  2692.  
  2693.         case MEN_EDIT_TRAPS:
  2694.  
  2695.             BlockWindows();
  2696.  
  2697.             TrapPanel();
  2698.  
  2699.             if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
  2700.             {
  2701.                 if(WatchTraps)
  2702.                     Item -> Flags &= ~CHECKED;
  2703.                 else
  2704.                     Item -> Flags |= CHECKED;
  2705.             }
  2706.  
  2707.             ReleaseWindows();
  2708.  
  2709.             break;
  2710.  
  2711.             /* Set the name we will use to open the
  2712.              * default console output window for
  2713.              * AmigaDOS commands and ARexx scripts.
  2714.              */
  2715.  
  2716.         case MEN_SET_CONSOLE:
  2717.  
  2718.             BlockWindows();
  2719.  
  2720.             if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_SET_CONSOLE_WINDOW_TXT),WindowName))
  2721.                 SetEnvDOS("TERMWINDOW",WindowName);
  2722.  
  2723.             ReleaseWindows();
  2724.  
  2725.             break;
  2726.  
  2727.             /* Open the phonebook and dial the
  2728.              * list of entries the user will select.
  2729.              */
  2730.  
  2731.         case MEN_PHONEBOOK:
  2732.  
  2733.             BlockWindows();
  2734.  
  2735.             HandleLocalDialList(TRUE);
  2736.  
  2737.             while(PhonePanel())
  2738.             {
  2739.                 if(!DialPanel())
  2740.                 {
  2741.                     Status = OldStatus;
  2742.  
  2743.                     break;
  2744.                 }
  2745.  
  2746.                 Status = OldStatus;
  2747.             }
  2748.  
  2749.             SetRedialMenu();
  2750.  
  2751.             ReleaseWindows();
  2752.  
  2753.             break;
  2754.  
  2755.             /* Redial those dial list entries which
  2756.              * we were unable to connect.
  2757.              */
  2758.  
  2759.         case MEN_REDIAL:
  2760.  
  2761.             BlockWindows();
  2762.  
  2763.             HandleLocalDialList(TRUE);
  2764.  
  2765.             do
  2766.             {
  2767.                 if(!DialPanel())
  2768.                 {
  2769.                     Status = OldStatus;
  2770.  
  2771.                     break;
  2772.                 }
  2773.  
  2774.                 Status = OldStatus;
  2775.             }
  2776.             while(PhonePanel());
  2777.  
  2778.             SetRedialMenu();
  2779.  
  2780.             ReleaseWindows();
  2781.  
  2782.             break;
  2783.  
  2784.             /* Dial a single number. */
  2785.  
  2786.         case MEN_DIAL_NUMBER:
  2787.  
  2788.             BlockWindows();
  2789.  
  2790.             HandleLocalDialList(TRUE);
  2791.  
  2792.             if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TXT),DialNumberBuffer))
  2793.             {
  2794.                 if(DialNumberBuffer[0])
  2795.                 {
  2796.                     struct List *LocalList;
  2797.  
  2798.                     if(LocalList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
  2799.                     {
  2800.                         struct PhoneNode    *DialNode;
  2801.                         LONG             Len = strlen(DialNumberBuffer);
  2802.  
  2803.                         NewList(LocalList);
  2804.  
  2805.                         if(DialNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode) + Len + 1,MEMF_ANY|MEMF_CLEAR))
  2806.                         {
  2807.                             DialNode -> VanillaNode . ln_Name = (char *)(DialNode + 1);
  2808.  
  2809.                             strcpy(DialNode -> VanillaNode . ln_Name,DialNumberBuffer);
  2810.  
  2811.                             AddTail(LocalList,&DialNode -> VanillaNode);
  2812.  
  2813.                             FreeDialList(TRUE);
  2814.  
  2815.                             DialList = LocalList;
  2816.  
  2817.                             DialPanel();
  2818.  
  2819.                             Status = OldStatus;
  2820.                         }
  2821.                         else
  2822.                             FreeVecPooled(LocalList);
  2823.                     }
  2824.                 }
  2825.             }
  2826.  
  2827.             SetRedialMenu();
  2828.  
  2829.             ReleaseWindows();
  2830.  
  2831.             break;
  2832.  
  2833.             /* Send a break across the serial line. */
  2834.  
  2835.         case MEN_SEND_BREAK:
  2836.  
  2837.             SendBreak();
  2838.             break;
  2839.  
  2840.             /* Hang up the phone line. */
  2841.  
  2842.         case MEN_HANG_UP:
  2843.  
  2844.             BlockWindows();
  2845.  
  2846.             if(DialMsg)
  2847.             {
  2848.                 DialMsg -> rm_Result1 = RC_WARN;
  2849.                 DialMsg -> rm_Result2 = 0;
  2850.  
  2851.                 ReplyMsg(DialMsg);
  2852.  
  2853.                 DialMsg = NULL;
  2854.             }
  2855.  
  2856.             HangUp();
  2857.  
  2858.             ReleaseWindows();
  2859.  
  2860.             if(Config -> SerialConfig -> CheckCarrier)
  2861.                 HungUp = TRUE;
  2862.             else
  2863.             {
  2864.                 ObtainSemaphore(&OnlineSemaphore);
  2865.  
  2866.                 if(Online)
  2867.                 {
  2868.                         /* Remember online state. */
  2869.  
  2870.                     WasOnline = Online;
  2871.  
  2872.                         /* We are no longer online. */
  2873.  
  2874.                     Online = FALSE;
  2875.                 }
  2876.  
  2877.                 ReleaseSemaphore(&OnlineSemaphore);
  2878.  
  2879.                 HandleOnlineCleanup(TRUE);
  2880.             }
  2881.  
  2882.             break;
  2883.  
  2884.             /* Wait a bit... */
  2885.  
  2886.         case MEN_WAIT:
  2887.         {
  2888.             struct Window        *ReqWindow;
  2889.             struct EasyStruct     Easy;
  2890.  
  2891.             Easy . es_StructSize    = sizeof(struct EasyStruct);
  2892.             Easy . es_Flags        = NULL;
  2893.             Easy . es_Title        = (UBYTE *)LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  2894.             Easy . es_GadgetFormat    = (UBYTE *)LocaleString(MSG_GLOBAL_CONTINUE_TXT);
  2895.             Easy . es_TextFormat    = (UBYTE *)LocaleString(MSG_TERMMAIN_WAITING_TXT);
  2896.  
  2897.             BlockWindows();
  2898.  
  2899.             if(ReqWindow = BuildEasyRequest(Window,&Easy,IDCMP_RAWKEY,NULL))
  2900.             {
  2901.                 ULONG    Signals;
  2902.                 BYTE    Done = FALSE;
  2903.  
  2904.                     /* Don't echo serial output. */
  2905.  
  2906.                 Quiet = TRUE;
  2907.  
  2908.                 do
  2909.                 {
  2910.                     SerWrite(" \b",2);
  2911.  
  2912.                     HandleSerial();
  2913.  
  2914.                     StartTime(1,0);
  2915.  
  2916.                     Signals = Wait(SIG_TIMER | PORTMASK(ReqWindow -> UserPort));
  2917.  
  2918.                     if(Signals & SIG_TIMER)
  2919.                         WaitIO(TimeRequest);
  2920.  
  2921.                     if(Signals & PORTMASK(ReqWindow -> UserPort))
  2922.                     {
  2923.                         LONG    Result;
  2924.                         ULONG    IDCMP = NULL;
  2925.  
  2926.                         Result = SysReqHandler(ReqWindow,&IDCMP,FALSE);
  2927.  
  2928.                         if(Result == 0 || (Result == -2 && !(IDCMP & IDCMP_RAWKEY)))
  2929.                         {
  2930.                             if(!CheckIO(TimeRequest))
  2931.                                 AbortIO(TimeRequest);
  2932.  
  2933.                             WaitIO(TimeRequest);
  2934.  
  2935.                             Done = TRUE;
  2936.                         }
  2937.                     }
  2938.                 }
  2939.                 while(!Done);
  2940.  
  2941.                 Quiet = FALSE;
  2942.  
  2943.                 FreeSysRequest(ReqWindow);
  2944.             }
  2945.  
  2946.             ReleaseWindows();
  2947.         }
  2948.  
  2949.         break;
  2950.  
  2951.             /* Flush the serial buffers. */
  2952.  
  2953.         case MEN_FLUSH_BUFFER:
  2954.  
  2955.             ClearSerial();
  2956.  
  2957.             RestartSerial(FALSE);
  2958.  
  2959.             break;
  2960.  
  2961.             /* Release the serial device for other
  2962.              * applications.
  2963.              */
  2964.  
  2965.         case MEN_RELEASE_DEVICE:
  2966.  
  2967.             ReleaseSerial = TRUE;
  2968.             break;
  2969.  
  2970.         case MEN_UPLOAD_ASCII:
  2971.  
  2972.             BlockWindows();
  2973.  
  2974.             if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
  2975.             {
  2976.                 BinaryTransfer = FALSE;
  2977.  
  2978.                 StartXprSend(TRANSFER_ASCII,TRUE);
  2979.  
  2980.                 BinaryTransfer = TRUE;
  2981.             }
  2982.  
  2983.             ResetProtocol();
  2984.  
  2985.             ReleaseWindows();
  2986.  
  2987.             break;
  2988.  
  2989.         case MEN_DOWNLOAD_ASCII:
  2990.  
  2991.             BlockWindows();
  2992.  
  2993.             if(ChangeProtocol(Config -> TransferConfig -> ASCIIDownloadLibrary,Config -> TransferConfig -> ASCIIDownloadType))
  2994.             {
  2995.                 BinaryTransfer = FALSE;
  2996.  
  2997.                 StartXprReceive(TRANSFER_ASCII,NULL,TRUE);
  2998.  
  2999.                 BinaryTransfer = TRUE;
  3000.             }
  3001.  
  3002.             ResetProtocol();
  3003.  
  3004.             ReleaseWindows();
  3005.  
  3006.             break;
  3007.  
  3008.         case MEN_UPLOAD_TEXT:
  3009.  
  3010.             BlockWindows();
  3011.  
  3012.             if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
  3013.             {
  3014.                 BinaryTransfer = FALSE;
  3015.  
  3016.                 StartXprSend(TRANSFER_TEXT,TRUE);
  3017.  
  3018.                 BinaryTransfer = TRUE;
  3019.             }
  3020.  
  3021.             ResetProtocol();
  3022.  
  3023.             ReleaseWindows();
  3024.  
  3025.             break;
  3026.  
  3027.         case MEN_DOWNLOAD_TEXT:
  3028.  
  3029.             BlockWindows();
  3030.  
  3031.             if(ChangeProtocol(Config -> TransferConfig -> TextDownloadLibrary,Config -> TransferConfig -> TextDownloadType))
  3032.             {
  3033.                 BinaryTransfer = FALSE;
  3034.  
  3035.                 StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
  3036.  
  3037.                 BinaryTransfer = TRUE;
  3038.             }
  3039.  
  3040.             ResetProtocol();
  3041.  
  3042.             ReleaseWindows();
  3043.  
  3044.             break;
  3045.  
  3046.             /* Edit and transfer a file. */
  3047.  
  3048.         case MEN_EDIT_AND_UPLOAD_TEXT:
  3049.  
  3050.             BlockWindows();
  3051.  
  3052.             if(!Config -> PathConfig -> Editor[0])
  3053.                 GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_NAME_OF_EDITOR_TO_USE_TXT),Config -> PathConfig -> Editor);
  3054.  
  3055.             if(Config -> PathConfig -> Editor[0])
  3056.             {
  3057.                 if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_EDIT_AND_TRANSFER_FILE_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMMAIN_EDIT_TXT),TRUE))
  3058.                 {
  3059.                     UBYTE CompoundName[512];
  3060.  
  3061.                     strcpy(CompoundName,Config -> PathConfig -> Editor);
  3062.                     strcat(CompoundName," \"");
  3063.                     strcat(CompoundName,DummyBuffer);
  3064.                     strcat(CompoundName,"\"");
  3065.  
  3066.                     LaunchCommand(CompoundName);
  3067.  
  3068.                     BumpWindow(Window);
  3069.  
  3070.                     FreeAslRequest(FileRequest);
  3071.  
  3072.                     if(GetFileSize(DummyBuffer))
  3073.                     {
  3074.                         BinaryTransfer = FALSE;
  3075.  
  3076.                         switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILE_AS_TXT),LocaleString(MSG_TERMMAIN_ASCII_UPLOAD_CANCEL_TXT),FilePart(DummyBuffer)))
  3077.                         {
  3078.                             case 1:    if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
  3079.                                     SendTextFile(TRANSFER_ASCII,DummyBuffer);
  3080.  
  3081.                                 ResetProtocol();
  3082.  
  3083.                                 break;
  3084.  
  3085.                             case 2:    if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
  3086.                                     SendTextFile(TRANSFER_TEXT,DummyBuffer);
  3087.  
  3088.                                 ResetProtocol();
  3089.  
  3090.                                 break;
  3091.                         }
  3092.  
  3093.                         BinaryTransfer = TRUE;
  3094.                     }
  3095.                 }
  3096.             }
  3097.  
  3098.             ReleaseWindows();
  3099.             break;
  3100.  
  3101.         case MEN_UPLOAD_BINARY:
  3102.  
  3103.             BlockWindows();
  3104.  
  3105.             if(ChangeProtocol(Config -> TransferConfig -> BinaryUploadLibrary,Config -> TransferConfig -> BinaryUploadType))
  3106.             {
  3107.                 BinaryTransfer = TRUE;
  3108.  
  3109.                 StartXprSend(TRANSFER_BINARY,TRUE);
  3110.             }
  3111.  
  3112.             ResetProtocol();
  3113.  
  3114.             ReleaseWindows();
  3115.  
  3116.             break;
  3117.  
  3118.             /* Download some files. */
  3119.  
  3120.         case MEN_DOWNLOAD_BINARY:
  3121.  
  3122.             BlockWindows();
  3123.  
  3124.             if(ChangeProtocol(Config -> TransferConfig -> BinaryDownloadLibrary,Config -> TransferConfig -> BinaryDownloadType))
  3125.             {
  3126.                 BinaryTransfer = TRUE;
  3127.  
  3128.                 StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
  3129.             }
  3130.  
  3131.             ResetProtocol();
  3132.  
  3133.             ReleaseWindows();
  3134.  
  3135.             break;
  3136.  
  3137.             /* Clear the contents of the scrollback
  3138.              * buffer.
  3139.              */
  3140.  
  3141.         case MEN_CLEAR_BUFFER:
  3142.  
  3143.             if(Lines)
  3144.             {
  3145.                 BlockWindows();
  3146.  
  3147.                 if((Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) || !Config -> MiscConfig -> ProtectiveMode)
  3148.                 {
  3149.                     FreeBuffer();
  3150.  
  3151.                     TerminateBuffer();
  3152.                 }
  3153.                 else
  3154.                 {
  3155.                     if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  3156.                     {
  3157.                         FreeBuffer();
  3158.  
  3159.                         TerminateBuffer();
  3160.                     }
  3161.                 }
  3162.  
  3163.                 ReleaseWindows();
  3164.             }
  3165.  
  3166.             break;
  3167.  
  3168.             /* Display the scrollback buffer.
  3169.              * Notify the scrollback task or
  3170.              * fire it off if approriate.
  3171.              */
  3172.  
  3173.         case MEN_DISPLAY_BUFFER:
  3174.  
  3175.             if(!LaunchBuffer())
  3176.             {
  3177.                 BlockWindows();
  3178.  
  3179.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNABLE_TO_CREATE_BUFFER_TASK_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3180.  
  3181.                 ReleaseWindows();
  3182.             }
  3183.  
  3184.             break;
  3185.  
  3186.             /* Close the buffer display. */
  3187.  
  3188.         case MEN_CLOSE_BUFFER:
  3189.  
  3190.             if(BufferTask)
  3191.             {
  3192.                 Forbid();
  3193.  
  3194.                 Signal(BufferTask,SIG_KILL);
  3195.  
  3196.                 ClrSignal(SIG_HANDSHAKE);
  3197.  
  3198.                 Wait(SIG_HANDSHAKE);
  3199.  
  3200.                 Permit();
  3201.             }
  3202.  
  3203.             break;
  3204.  
  3205.             /* Is the buffer to be frozen? */
  3206.  
  3207.         case MEN_FREEZE_BUFFER:
  3208.  
  3209.             if(Item = FindThisItem(Menu,MEN_FREEZE_BUFFER))
  3210.             {
  3211.                 if(Item -> Flags & CHECKED)
  3212.                     BufferFrozen = TRUE;
  3213.                 else
  3214.                     BufferFrozen = FALSE;
  3215.  
  3216.                 Forbid();
  3217.  
  3218.                 ConOutputUpdate();
  3219.  
  3220.                 Permit();
  3221.             }
  3222.  
  3223.             break;
  3224.  
  3225.             /* Load the buffer contents from a file. */
  3226.  
  3227.         case MEN_OPEN_BUFFER:
  3228.  
  3229.             BlockWindows();
  3230.  
  3231.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),FALSE))
  3232.             {
  3233.                 if(GetFileSize(DummyBuffer))
  3234.                 {
  3235.                     if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  3236.                     {
  3237.                         if(Lines)
  3238.                         {
  3239.                             switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_TERMMAIN_DISCARD_APPPEND_CANCEL_TXT),Lines))
  3240.                             {
  3241.                                 case 1:    FreeBuffer();
  3242.                                     break;
  3243.  
  3244.                                 case 2:    break;
  3245.  
  3246.                                 case 0:    Close(SomeFile);
  3247.                                     SomeFile = NULL;
  3248.                                     break;
  3249.                             }
  3250.                         }
  3251.  
  3252.                         if(SomeFile)
  3253.                         {
  3254.                             LONG Len;
  3255.  
  3256.                             LineRead(NULL,NULL,NULL);
  3257.  
  3258.                             while((Len = LineRead(SomeFile,DummyBuffer,80)) > 0)
  3259.                                 CaptureParser(DummyBuffer,Len,AddLine);
  3260.  
  3261.                             Close(SomeFile);
  3262.  
  3263.                             BufferChanged = TRUE;
  3264.                         }
  3265.                     }
  3266.                     else
  3267.                         ShowError(Window,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
  3268.                 }
  3269.  
  3270.                 FreeAslRequest(FileRequest);
  3271.             }
  3272.  
  3273.             ReleaseWindows();
  3274.             break;
  3275.  
  3276.             /* Save the contents of the scrollback
  3277.              * buffer to a file (line by line).
  3278.              */
  3279.  
  3280.         case MEN_SAVE_BUFFER_AS:
  3281.  
  3282.             BlockWindows();
  3283.  
  3284.             if(!Lines || !BufferLines)
  3285.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3286.             else
  3287.             {
  3288.                 if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT),Config -> CaptureConfig -> BufferPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  3289.                 {
  3290.                     LONG Error = 0;
  3291.  
  3292.                     SomeFile = NULL;
  3293.  
  3294.                         /* If the file we are about
  3295.                          * to create already exists,
  3296.                          * ask the user whether we are
  3297.                          * to create, append or skip
  3298.                          * the file.
  3299.                          */
  3300.  
  3301.                     if(GetFileSize(DummyBuffer))
  3302.                     {
  3303.                         switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  3304.                         {
  3305.                             case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3306.                                 break;
  3307.  
  3308.                             case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  3309.                                 {
  3310.                                     if(Seek(SomeFile,0,OFFSET_END) == -1)
  3311.                                     {
  3312.                                         Close(SomeFile);
  3313.  
  3314.                                         SomeFile = NULL;
  3315.                                     }
  3316.                                 }
  3317.  
  3318.                                 break;
  3319.                         }
  3320.                     }
  3321.                     else
  3322.                         SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3323.  
  3324.                     if(SomeFile)
  3325.                     {
  3326.                         LONG i,Len;
  3327.  
  3328.                             /* Obtain the semaphore required
  3329.                              * to gain access to the line buffer
  3330.                              */
  3331.  
  3332.                         ObtainSemaphore(BufferSemaphore);
  3333.  
  3334.                         for(i = 0 ; i < Lines ; i++)
  3335.                         {
  3336.                             Len = BufferLines[i][-1];
  3337.  
  3338.                             if(Len)
  3339.                             {
  3340.                                 SetIoErr(0);
  3341.  
  3342.                                 if(FWrite(SomeFile,BufferLines[i],Len,1) < 1)
  3343.                                 {
  3344.                                     Error = IoErr();
  3345.  
  3346.                                     break;
  3347.                                 }
  3348.                             }
  3349.  
  3350.                             SetIoErr(0);
  3351.  
  3352.                             if(FPrintf(SomeFile,"\n") < 1)
  3353.                             {
  3354.                                 Error = IoErr();
  3355.  
  3356.                                 break;
  3357.                             }
  3358.                         }
  3359.  
  3360.                         ReleaseSemaphore(BufferSemaphore);
  3361.  
  3362.                         Close(SomeFile);
  3363.  
  3364.                         AddProtection(DummyBuffer,FIBF_EXECUTE);
  3365.  
  3366.                         if(Config -> MiscConfig -> CreateIcons)
  3367.                             AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  3368.  
  3369.                         BufferChanged = FALSE;
  3370.                     }
  3371.                     else
  3372.                         Error = IoErr();
  3373.  
  3374.                     if(Error)
  3375.                         ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  3376.  
  3377.                     FreeAslRequest(FileRequest);
  3378.                 }
  3379.             }
  3380.  
  3381.             ReleaseWindows();
  3382.  
  3383.             break;
  3384.  
  3385.             /* Simply clear the screen and move the
  3386.              * cursor to its home position.
  3387.              */
  3388.  
  3389.         case MEN_CLEAR_SCREEN:
  3390.  
  3391.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3392.                 XEmulatorClearConsole(XEM_IO);
  3393.             else
  3394.             {
  3395.                 DropMarker();
  3396.  
  3397.                 ConBypass("\033[2J\033[H",-1);
  3398.             }
  3399.  
  3400.             break;
  3401.  
  3402.             /* Reset the current text rendering font. */
  3403.  
  3404.         case MEN_RESET_FONT:
  3405.  
  3406.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3407.                 XEmulatorResetCharset(XEM_IO);
  3408.             else
  3409.             {
  3410.                 DropMarker();
  3411.  
  3412.                 CurrentFont = TextFont;
  3413.  
  3414.                 SetFont(RPort,CurrentFont);
  3415.  
  3416.                 ConOutputUpdate();
  3417.             }
  3418.  
  3419.             break;
  3420.  
  3421.             /* Reset the display styles and restore
  3422.              * the colours.
  3423.              */
  3424.  
  3425.         case MEN_RESET_STYLES:
  3426.  
  3427.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3428.                 XEmulatorResetTextStyles(XEM_IO);
  3429.             else
  3430.             {
  3431.                 DropMarker();
  3432.  
  3433.                 ConBypass("\033[0m",-1);
  3434.  
  3435.                 ObtainSemaphore(&TerminalSemaphore);
  3436.  
  3437.                 ClearCursor();
  3438.  
  3439.                 Config -> EmulationConfig -> FontScale = SCALE_NORMAL;
  3440.  
  3441.                 if(!Config -> EmulationConfig -> LockColour)
  3442.                 {
  3443.                     ForegroundPen = GetPenIndex(SafeTextPen);
  3444.                     BackgroundPen = 0;
  3445.                 }
  3446.  
  3447.                 SetMask(RPort,DepthMask);
  3448.  
  3449.                 UpdatePens();
  3450.  
  3451.                 ConFontScaleUpdate();
  3452.  
  3453.                 DrawCursor();
  3454.  
  3455.                 ReleaseSemaphore(&TerminalSemaphore);
  3456.             }
  3457.  
  3458.             break;
  3459.  
  3460.             /* Reset the whole terminal. */
  3461.  
  3462.         case MEN_RESET_TERMINAL:
  3463.  
  3464.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3465.                 XEmulatorResetConsole(XEM_IO);
  3466.             else
  3467.             {
  3468.                 FreeMarker();
  3469.  
  3470.                 ConBypass("\033c",-1);
  3471.             }
  3472.  
  3473.             break;
  3474.  
  3475.         case MEN_SET_EMULATION:
  3476.  
  3477.             BlockWindows();
  3478.  
  3479.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3480.             {
  3481.                 OptionTitle = LocaleString(MSG_TERMMAIN_EMULATION_PREFERENCES_TXT);
  3482.  
  3483.                 NewOptions = FALSE;
  3484.  
  3485.                 XEmulatorOptions(XEM_IO);
  3486.  
  3487.                 if(NewOptions)
  3488.                 {
  3489.                     SetEmulatorOptions(XEM_PREFS_SAVE);
  3490.  
  3491.                     NewOptions = FALSE;
  3492.                 }
  3493.  
  3494.                 OptionTitle = NULL;
  3495.             }
  3496.             else
  3497.             {
  3498.                 if(EmulationPanel(Config,NULL))
  3499.                 {
  3500.                     ConfigSetup();
  3501.  
  3502.                     ConfigChanged = TRUE;
  3503.                 }
  3504.             }
  3505.  
  3506.             ReleaseWindows();
  3507.  
  3508.             break;
  3509.  
  3510.             /* Set the serial preferences. */
  3511.  
  3512.         case MEN_SERIAL:
  3513.  
  3514.             BlockWindows();
  3515.  
  3516.             if(SerialPanel(Config,NULL))
  3517.             {
  3518.                 ConfigSetup();
  3519.  
  3520.                 ConfigChanged = TRUE;
  3521.             }
  3522.  
  3523.             ReleaseWindows();
  3524.  
  3525.             break;
  3526.  
  3527.             /* Set the modem preferences. */
  3528.  
  3529.         case MEN_MODEM:
  3530.  
  3531.             BlockWindows();
  3532.  
  3533.             if(ModemPanel(Config,NULL))
  3534.             {
  3535.                 FlowInit(TRUE);
  3536.  
  3537.                 ConfigChanged = TRUE;
  3538.             }
  3539.  
  3540.             ReleaseWindows();
  3541.  
  3542.             break;
  3543.  
  3544.             /* Set the screen preferences. */
  3545.  
  3546.         case MEN_SCREEN:
  3547.  
  3548.             BlockWindows();
  3549.  
  3550.             if(ScreenPanel(Config,NULL))
  3551.             {
  3552.                 if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
  3553.                 {
  3554.                     switch(Config -> ScreenConfig -> ColourMode)
  3555.                     {
  3556.                         case COLOUR_EIGHT:
  3557.  
  3558.                             CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
  3559.                             break;
  3560.  
  3561.                         case COLOUR_SIXTEEN:
  3562.  
  3563.                             CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
  3564.                             break;
  3565.  
  3566.                         case COLOUR_AMIGA:
  3567.  
  3568.                             CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
  3569.                             break;
  3570.  
  3571.                         case COLOUR_MONO:
  3572.  
  3573.                             CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
  3574.                             break;
  3575.                     }
  3576.                 }
  3577.  
  3578.                 ConfigSetup();
  3579.  
  3580.                 ConfigChanged = TRUE;
  3581.             }
  3582.             else
  3583.             {
  3584.                 if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
  3585.                 {
  3586.                     switch(Config -> ScreenConfig -> ColourMode)
  3587.                     {
  3588.                         case COLOUR_EIGHT:
  3589.  
  3590.                             CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
  3591.                             break;
  3592.  
  3593.                         case COLOUR_SIXTEEN:
  3594.  
  3595.                             CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
  3596.                             break;
  3597.  
  3598.                         case COLOUR_AMIGA:
  3599.  
  3600.                             CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
  3601.                             break;
  3602.  
  3603.                         case COLOUR_MONO:
  3604.  
  3605.                             CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
  3606.                             break;
  3607.                     }
  3608.  
  3609.                     ConfigChanged = TRUE;
  3610.                 }
  3611.             }
  3612.  
  3613.             ReleaseWindows();
  3614.  
  3615.             break;
  3616.  
  3617.             /* Set the terminal preferences. */
  3618.  
  3619.         case MEN_TERMINAL:
  3620.  
  3621.             BlockWindows();
  3622.  
  3623.             if(TerminalPanel(Config,NULL))
  3624.             {
  3625.                 Update_CR_LF_Translation();
  3626.  
  3627.                 ConfigSetup();
  3628.  
  3629.                 ConfigChanged = TRUE;
  3630.             }
  3631.  
  3632.             ReleaseWindows();
  3633.  
  3634.             break;
  3635.  
  3636.             /* Set the clipboard preferences. */
  3637.  
  3638.         case MEN_CLIPBOARD:
  3639.  
  3640.             BlockWindows();
  3641.  
  3642.             if(ClipPanel(Config,NULL))
  3643.             {
  3644.                 ConfigSetup();
  3645.  
  3646.                 ConfigChanged = TRUE;
  3647.             }
  3648.  
  3649.             ReleaseWindows();
  3650.  
  3651.             break;
  3652.  
  3653.             /* Set the capture preferences. */
  3654.  
  3655.         case MEN_CAPTURE:
  3656.  
  3657.             BlockWindows();
  3658.  
  3659.             if(CapturePanel(Config,NULL))
  3660.             {
  3661.                 ConOutputUpdate();
  3662.  
  3663.                 ConfigSetup();
  3664.  
  3665.                 ConfigChanged = TRUE;
  3666.             }
  3667.  
  3668.             ReleaseWindows();
  3669.  
  3670.             break;
  3671.  
  3672.             /* Set the command preferences. */
  3673.  
  3674.         case MEN_COMMANDS:
  3675.  
  3676.             BlockWindows();
  3677.  
  3678.             if(CommandPanel(Config,NULL))
  3679.                 ConfigChanged = TRUE;
  3680.  
  3681.             ReleaseWindows();
  3682.  
  3683.             break;
  3684.  
  3685.             /* Set the miscellaneous preferences. */
  3686.  
  3687.         case MEN_MISC:
  3688.  
  3689.             BlockWindows();
  3690.  
  3691.             if(MiscPanel(Config,NULL))
  3692.             {
  3693.                 ConfigSetup();
  3694.  
  3695.                 ConfigChanged = TRUE;
  3696.             }
  3697.  
  3698.             ReleaseWindows();
  3699.  
  3700.             break;
  3701.  
  3702.             /* Set the path settings. */
  3703.  
  3704.         case MEN_PATH:
  3705.  
  3706.             BlockWindows();
  3707.  
  3708.             if(PathPanel(Config,NULL))
  3709.                 ConfigChanged = TRUE;
  3710.  
  3711.             ReleaseWindows();
  3712.  
  3713.             break;
  3714.  
  3715.             /* Set the file transfer options. */
  3716.  
  3717.         case MEN_TRANSFER:
  3718.  
  3719.             BlockWindows();
  3720.  
  3721.             XprIO -> xpr_filename = NULL;
  3722.  
  3723.                 /* Set up the library options. */
  3724.  
  3725.             if(XProtocolBase)
  3726.             {
  3727.                 XPRCommandSelected = FALSE;
  3728.  
  3729.                 ClearSerial();
  3730.  
  3731.                 NewOptions = FALSE;
  3732.  
  3733.                 TransferBits = XProtocolSetup(XprIO);
  3734.  
  3735.                 RestartSerial(FALSE);
  3736.  
  3737.                 DeleteTransferPanel(TRUE);
  3738.  
  3739.                     /* Successful? */
  3740.  
  3741. /*                if(!XPRCommandSelected)*/
  3742.                 {
  3743.                     if(!(TransferBits & XPRS_SUCCESS))
  3744.                     {
  3745.                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  3746.  
  3747.                         CloseLibrary(XProtocolBase);
  3748.  
  3749.                         XProtocolBase = NULL;
  3750.  
  3751.                         LastXprLibrary[0] = 0;
  3752.  
  3753.                         TransferBits = 0;
  3754.  
  3755.                         SetTransferMenu(FALSE);
  3756.                     }
  3757.                     else
  3758.                         SaveProtocolOpts();
  3759.                 }
  3760.             }
  3761.  
  3762.             ReleaseWindows();
  3763.  
  3764.             break;
  3765.  
  3766.             /* Set the file transfer procol settings. */
  3767.  
  3768.         case MEN_TRANSFER_PROTOCOL:
  3769.  
  3770.             BlockWindows();
  3771.  
  3772.             if(LibPanel(Config,NULL))
  3773.             {
  3774.                 ConfigSetup();
  3775.  
  3776.                 ConfigChanged = TRUE;
  3777.  
  3778.                 FlowInit(TRUE);
  3779.             }
  3780.  
  3781.             ReleaseWindows();
  3782.  
  3783.             break;
  3784.  
  3785.             /* Set the translation tables. */
  3786.  
  3787.         case MEN_TRANSLATION:
  3788.  
  3789.             BlockWindows();
  3790.  
  3791.             TranslationChanged |= TranslationPanel(&SendTable,&ReceiveTable,LastTranslation,Window);
  3792.  
  3793.                 /* Choose the right console write routine. */
  3794.  
  3795.             ConOutputUpdate();
  3796.  
  3797.             ReleaseWindows();
  3798.  
  3799.             break;
  3800.  
  3801.             /* Set the keyboard macros. */
  3802.  
  3803.         case MEN_MACROS:
  3804.  
  3805.             BlockWindows();
  3806.  
  3807.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3808.             {
  3809.                 XEmulatorMacroKeyFilter(XEM_IO,NULL);
  3810.  
  3811.                 MacroChanged |= MacroPanel(MacroKeys,LastMacros,TRUE,Window);
  3812.  
  3813.                 SetupXEM_MacroKeys(MacroKeys);
  3814.             }
  3815.             else
  3816.                 MacroChanged |= MacroPanel(MacroKeys,LastMacros,TRUE,Window);
  3817.  
  3818.             ReleaseWindows();
  3819.  
  3820.             break;
  3821.  
  3822.             /* Set the cursor keys. */
  3823.  
  3824.         case MEN_CURSORKEYS:
  3825.  
  3826.             BlockWindows();
  3827.  
  3828.             CursorKeysChanged |= CursorPanel(CursorKeys,LastCursorKeys,Window);
  3829.  
  3830.             ReleaseWindows();
  3831.  
  3832.             break;
  3833.  
  3834.             /* Set the fast macros. */
  3835.  
  3836.         case MEN_FAST_MACROS:
  3837.  
  3838.             BlockWindows();
  3839.  
  3840.             FastMacrosChanged |= FastMacroPanel(&FastMacroList,LastFastMacros,Window);
  3841.  
  3842.             ReleaseWindows();
  3843.  
  3844.             break;
  3845.  
  3846.             /* Set the hotkey preferences. */
  3847.  
  3848.         case MEN_HOTKEYS:
  3849.  
  3850.             BlockWindows();
  3851.  
  3852.             if(HotkeyPanel(&Hotkeys))
  3853.             {
  3854.                 if(!SetupCx())
  3855.                     MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_SET_UP_HOTKEYS_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3856.             }
  3857.  
  3858.             ReleaseWindows();
  3859.  
  3860.             break;
  3861.  
  3862.             /* Set the speech preferences. */
  3863.  
  3864.         case MEN_SPEECH:
  3865.  
  3866.             BlockWindows();
  3867.  
  3868.             SpeechPanel();
  3869.  
  3870.             ReleaseWindows();
  3871.  
  3872.             break;
  3873.  
  3874.             /* Set the sound preferences. */
  3875.  
  3876.         case MEN_SOUND:
  3877.  
  3878.             BlockWindows();
  3879.  
  3880.             if(SoundPanel(&SoundConfig))
  3881.                 SoundInit();
  3882.  
  3883.             ReleaseWindows();
  3884.  
  3885.             break;
  3886.  
  3887.             /* Edit the phone number patterns and rates. */
  3888.  
  3889.             /* Edit the trap settings? */
  3890.  
  3891.         case MEN_RATES:
  3892.  
  3893.             BlockWindows();
  3894.  
  3895.             PatternPanel();
  3896.  
  3897.             ReleaseWindows();
  3898.  
  3899.             break;
  3900.  
  3901.             /* Open the preferences settings. */
  3902.  
  3903.         case MEN_OPEN_SETTINGS:
  3904.  
  3905.             BlockWindows();
  3906.  
  3907.             strcpy(DummyBuffer,LastConfig);
  3908.  
  3909.             DummyChar = PathPart(DummyBuffer);
  3910.  
  3911.             *DummyChar = 0;
  3912.  
  3913.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",FALSE,FALSE,FALSE,NULL,TRUE))
  3914.             {
  3915.                 if(ReadConfig(DummyBuffer,PrivateConfig))
  3916.                 {
  3917.                     SwapConfig(PrivateConfig,Config);
  3918.  
  3919.                     strcpy(DummyBuffer,LastConfig);
  3920.  
  3921.                     ConfigSetup();
  3922.  
  3923.                     ConfigChanged = FALSE;
  3924.                 }
  3925.                 else
  3926.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  3927.  
  3928.                 FreeAslRequest(FileRequest);
  3929.             }
  3930.  
  3931.             ReleaseWindows();
  3932.  
  3933.             break;
  3934.  
  3935.             /* Save the terminal preferences. */
  3936.  
  3937.         case MEN_SAVE_SETTINGS:
  3938.  
  3939.             if(LastConfig[0])
  3940.             {
  3941.                 BlockWindows();
  3942.  
  3943.                 if(!Screen)
  3944.                     PutWindowInfo(WINDOW_MAIN,Window -> LeftEdge,Window -> TopEdge,Window -> Width,Window -> Height);
  3945.  
  3946.                 if(!WriteConfig(LastConfig,Config))
  3947.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),LastConfig);
  3948.                 else
  3949.                     ConfigChanged = FALSE;
  3950.  
  3951.                 ReleaseWindows();
  3952.  
  3953.                 break;
  3954.             }
  3955.  
  3956.             /* Save the terminal preferences to a
  3957.              * given file name.
  3958.              */
  3959.  
  3960.         case MEN_SAVE_SETTINGS_AS:
  3961.  
  3962.             BlockWindows();
  3963.  
  3964.             strcpy(DummyBuffer,LastConfig);
  3965.  
  3966.             DummyChar = PathPart(DummyBuffer);
  3967.  
  3968.             *DummyChar = 0;
  3969.  
  3970.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",TRUE,FALSE,FALSE,NULL,TRUE))
  3971.             {
  3972.                 if(!Screen)
  3973.                     PutWindowInfo(WINDOW_MAIN,Window -> LeftEdge,Window -> TopEdge,Window -> Width,Window -> Height);
  3974.  
  3975.                 if(WriteConfig(DummyBuffer,Config))
  3976.                 {
  3977.                     strcpy(LastConfig,DummyBuffer);
  3978.  
  3979.                     ConfigChanged = FALSE;
  3980.                 }
  3981.                 else
  3982.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  3983.  
  3984.                 FreeAslRequest(FileRequest);
  3985.             }
  3986.  
  3987.             ReleaseWindows();
  3988.  
  3989.             break;
  3990.  
  3991.             /* Show terminal information window. */
  3992.  
  3993.         case MEN_STATUS_WINDOW:
  3994.  
  3995.             if(InfoWindow)
  3996.                 CloseInfoWindow();
  3997.             else
  3998.                 OpenInfoWindow();
  3999.  
  4000.             break;
  4001.  
  4002.         case MEN_REVIEW_WINDOW:
  4003.  
  4004.             if(ReviewWindow)
  4005.                 DeleteReview();
  4006.             else
  4007.                 CreateReview();
  4008.  
  4009.             break;
  4010.  
  4011.             /* Open the packet window if necessary, else
  4012.              * just activate it.
  4013.              */
  4014.  
  4015.         case MEN_PACKET_WINDOW:
  4016.  
  4017.             CreatePacketWindow();
  4018.             break;
  4019.  
  4020.             // Enable or disable the packet window
  4021.  
  4022.         case MEN_CHAT_LINE:
  4023.  
  4024.             if(Item = FindThisItem(Menu,MEN_CHAT_LINE))
  4025.             {
  4026.                 BOOL NewState;
  4027.  
  4028.                 if(Item -> Flags & CHECKED)
  4029.                     NewState = TRUE;
  4030.                 else
  4031.                     NewState = FALSE;
  4032.  
  4033.                 if(ChatMode != NewState)
  4034.                 {
  4035.                     ChatMode = NewState;
  4036.  
  4037.                     ResetDisplay = TRUE;
  4038.                 }
  4039.             }
  4040.  
  4041.             break;
  4042.  
  4043.             /* Toggle the presence of the fast! macro panel. */
  4044.  
  4045.         case MEN_FAST_MACROS_WINDOW:
  4046.  
  4047.             if(FastWindow)
  4048.                 CloseFastWindow();
  4049.             else
  4050.                 OpenFastWindow();
  4051.  
  4052.             break;
  4053.  
  4054.             /* Open the upload queue window. */
  4055.  
  4056.         case MEN_UPLOAD_QUEUE_WINDOW:
  4057.  
  4058.             CreateQueueProcess();
  4059.             break;
  4060.  
  4061.         default:if(Code >= DIAL_MENU_LIMIT)
  4062.             {
  4063.                 LONG Index = Code - DIAL_MENU_LIMIT;
  4064.  
  4065.                 ObtainSemaphore(&OnlineSemaphore);
  4066.  
  4067.                 if(!LocalDialList && !Online)
  4068.                 {
  4069.                     ReleaseSemaphore(&OnlineSemaphore);
  4070.  
  4071.                     if(LocalDialList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY))
  4072.                     {
  4073.                         LONG i;
  4074.  
  4075.                             /* Clear previous list contents, we
  4076.                              * don't want to redial yet.
  4077.                              */
  4078.  
  4079.                         for(i = 0 ; i < NumPhoneEntries ; i++)
  4080.                             Phonebook[i] -> Count = -1;
  4081.  
  4082.                         NewList(LocalDialList);
  4083.                     }
  4084.                 }
  4085.                 else
  4086.                     ReleaseSemaphore(&OnlineSemaphore);
  4087.  
  4088.                 if(Phonebook[Index] -> Count == -1)
  4089.                 {
  4090.                     if(LocalDialList)
  4091.                     {
  4092.                         struct PhoneNode *NewNode;
  4093.  
  4094.                             /* Create a new node to be added to the dial list. */
  4095.  
  4096.                         if(NewNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode),MEMF_ANY | MEMF_CLEAR))
  4097.                         {
  4098.                                 /* Take care of the name and the corresponding phone book entry. */
  4099.  
  4100.                             NewNode -> VanillaNode . ln_Name    = NewNode -> LocalName;
  4101.                             NewNode -> Entry            = Phonebook[Index];
  4102.  
  4103.                             Phonebook[Index] -> Count = ++LocalCount;
  4104.  
  4105.                             SPrintf(NewNode -> LocalName,"%3ld - %s",LocalCount + 1,Phonebook[Index] -> Header -> Name);
  4106.  
  4107.                                 /* Install back-link. */
  4108.  
  4109.                             NewNode -> Entry -> Node = NewNode;
  4110.  
  4111.                             AddTail(LocalDialList,&NewNode -> VanillaNode);
  4112.                         }
  4113.                     }
  4114.                 }
  4115.             }
  4116.  
  4117.             break;
  4118.     }
  4119. }
  4120.  
  4121.     /* HandleMenu(ULONG Code,ULONG Qualifier):
  4122.      *
  4123.      *    Skip along the number of selected menu items and
  4124.      *    handle the associated functions.
  4125.      */
  4126.  
  4127. VOID __regargs
  4128. HandleMenu(ULONG Code,ULONG Qualifier)
  4129. {
  4130.     struct MenuItem *MenuItem;
  4131.  
  4132.     DisplayReopened = FALSE;
  4133.  
  4134.         /* Check until the last menuitem has been
  4135.          * processed.
  4136.          */
  4137.  
  4138.     while(Code != MENUNULL)
  4139.     {
  4140.             /* Pick up the associated menu item. */
  4141.  
  4142.         if(MenuItem = ItemAddress(Menu,Code))
  4143.         {
  4144.             HandleMenuCode((ULONG)GTMENUITEM_USERDATA(MenuItem),Qualifier);
  4145.  
  4146.             if(Apocalypse)
  4147.                 return;
  4148.  
  4149.             if(DisplayReopened)
  4150.             {
  4151.                 DisplayReopened = FALSE;
  4152.  
  4153.                 return;
  4154.             }
  4155.  
  4156.             Code = MenuItem -> NextSelect;
  4157.         }
  4158.         else
  4159.             break;
  4160.     }
  4161.  
  4162.     HandleLocalDialList(FALSE);
  4163. }
  4164.  
  4165.     /* HandleWorkbenchWindow():
  4166.      *
  4167.      *    Handle input coming from the Workbench window.
  4168.      */
  4169.  
  4170. BYTE
  4171. HandleWorkbenchWindow()
  4172. {
  4173.     struct FileInfoBlock    *FileInfo;
  4174.     struct AppMessage    *AppMessage;
  4175.  
  4176.     if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  4177.     {
  4178.         struct FileTransferInfo *Info;
  4179.  
  4180.         if(Info = AllocFileTransferInfo())
  4181.         {
  4182.             LONG FilesFound = 0,i;
  4183.             BYTE Success = TRUE;
  4184.  
  4185.             while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
  4186.             {
  4187.                 if(Success && AppMessage -> am_Type == MTYPE_APPWINDOW)
  4188.                 {
  4189.                     for(i = 0 ; Success && i < AppMessage -> am_NumArgs ; i++)
  4190.                     {
  4191.                         if(AppMessage -> am_ArgList[i] . wa_Lock && AppMessage -> am_ArgList[i] . wa_Name)
  4192.                         {
  4193.                             BPTR OldLock;
  4194.  
  4195.                             if(OldLock = CurrentDir(AppMessage -> am_ArgList[i] . wa_Lock))
  4196.                             {
  4197.                                 BPTR FileLock;
  4198.  
  4199.                                 if(FileLock = Lock(AppMessage -> am_ArgList[i] . wa_Name,ACCESS_READ))
  4200.                                 {
  4201.                                     if(Examine(FileLock,FileInfo))
  4202.                                     {
  4203.                                         if(FileInfo -> fib_DirEntryType < 0)
  4204.                                         {
  4205.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  4206.                                             {
  4207.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  4208.                                                     Success = FALSE;
  4209.                                                 else
  4210.                                                 {
  4211.                                                     FilesFound++;
  4212.  
  4213.                                                     if(Config -> TransferConfig -> TransferIcons)
  4214.                                                     {
  4215.                                                         BPTR InfoLock;
  4216.  
  4217.                                                         strcat(SharedBuffer,".info");
  4218.  
  4219.                                                         if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
  4220.                                                         {
  4221.                                                             if(Examine(InfoLock,FileInfo))
  4222.                                                             {
  4223.                                                                 if(FileInfo -> fib_DirEntryType < 0)
  4224.                                                                 {
  4225.                                                                     if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  4226.                                                                         Success = FALSE;
  4227.                                                                     else
  4228.                                                                         FilesFound++;
  4229.                                                                 }
  4230.                                                             }
  4231.  
  4232.                                                             UnLock(InfoLock);
  4233.                                                         }
  4234.                                                     }
  4235.                                                 }
  4236.                                             }
  4237.                                         }
  4238.                                     }
  4239.  
  4240.                                     UnLock(FileLock);
  4241.                                 }
  4242.  
  4243.                                 CurrentDir(OldLock);
  4244.                             }
  4245.                         }
  4246.                     }
  4247.                 }
  4248.  
  4249.                 ReplyMsg((struct Message *)AppMessage);
  4250.             }
  4251.  
  4252.             if(FilesFound)
  4253.             {
  4254.                 SortFileTransferInfo(Info);
  4255.  
  4256.                 BlockWindows();
  4257.  
  4258.                 switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILES_AS_TXT),LocaleString(MSG_TERMMAIN_BINARY_UPLOAD_CANCEL_TXT)))
  4259.                 {
  4260.                     case 1:    BinaryTransfer        = TRUE;
  4261.                         FileTransferInfo    = Info;
  4262.  
  4263.                         StartXprSendFromList(TRANSFER_BINARY,TRUE);
  4264.  
  4265.                         break;
  4266.  
  4267.                     case 2:    BinaryTransfer        = FALSE;
  4268.                         FileTransferInfo    = Info;
  4269.  
  4270.                         StartXprSendFromList(TRANSFER_TEXT,TRUE);
  4271.  
  4272.                         break;
  4273.  
  4274.                     case 0:    FreeFileTransferInfo(Info);
  4275.                         break;
  4276.                 }
  4277.  
  4278.                 ReleaseWindows();
  4279.             }
  4280.         }
  4281.  
  4282.         FreeDosObject(DOS_FIB,FileInfo);
  4283.     }
  4284.  
  4285.     while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
  4286.         ReplyMsg((struct Message *)AppMessage);
  4287.  
  4288.     return(FALSE);
  4289. }
  4290.  
  4291.     /* HandleIconify():
  4292.      *
  4293.      *    Handle program iconification.
  4294.      */
  4295.  
  4296. VOID
  4297. HandleIconify()
  4298. {
  4299.     BYTE Released = FALSE;
  4300.  
  4301.         /* Set the wait mouse pointer... */
  4302.  
  4303.     BlockWindows();
  4304.  
  4305.         /* Open workbench.library. */
  4306.  
  4307.     if(WorkbenchBase)
  4308.     {
  4309.             /* Open icon.library. */
  4310.  
  4311.         if(IconBase)
  4312.         {
  4313.             struct DiskObject *Icon;
  4314.  
  4315.             if(!(Icon = GetProgramIcon()))
  4316.                 Icon = GetDefDiskObject(WBTOOL);
  4317.  
  4318.                 /* Did we get an icon? */
  4319.  
  4320.             if(Icon)
  4321.             {
  4322.                 struct MsgPort *IconPort;
  4323.  
  4324.                     /* Reset the icon type. */
  4325.  
  4326.                 Icon -> do_Type        = NULL;
  4327.  
  4328.                     /* Default icon position. */
  4329.  
  4330.                 Icon -> do_CurrentX    = NO_ICON_POSITION;
  4331.                 Icon -> do_CurrentY    = NO_ICON_POSITION;
  4332.  
  4333.                     /* Create the Workbench reply port. */
  4334.  
  4335.                 if(IconPort = CreateMsgPort())
  4336.                 {
  4337.                     struct AppIcon *AppIcon;
  4338.  
  4339.                         /* Add the application icon. */
  4340.  
  4341.                     if(AppIcon = AddAppIcon(0,0,TermIDString,IconPort,NULL,Icon,TAG_DONE))
  4342.                     {
  4343.                         struct AppMessage    *AppMessage;
  4344.                         UBYTE            *String,*Error;
  4345.                         ULONG             SignalSet;
  4346.  
  4347.                             /* Reset the guardian. */
  4348.  
  4349.                         IconTerminated = FALSE;
  4350.  
  4351.                             /* Release the window. */
  4352.  
  4353.                         Released = TRUE;
  4354.  
  4355.                         ReleaseWindows();
  4356.  
  4357.                         WindowBox . Left    = Window -> LeftEdge;
  4358.                         WindowBox . Top        = Window -> TopEdge;
  4359.                         WindowBox . Width    = Window -> Width;
  4360.                         WindowBox . Height    = Window -> Height;
  4361.  
  4362.                             /* Close the display. full stop. */
  4363.  
  4364.                         if(DeleteDisplay())
  4365.                         {
  4366.                                 /* Reset and release the serial driver. */
  4367.  
  4368.                             if(Config -> MiscConfig -> ReleaseDevice)
  4369.                             {
  4370.                                 ClearSerial();
  4371.  
  4372.                                 DeleteSerial();
  4373.                             }
  4374.  
  4375.                                 /* Wait for double-click. */
  4376.  
  4377. IconLoop:                        while(!IconTerminated)
  4378.                             {
  4379.                                 SignalSet = Wait(PORTMASK(IconPort) | SIG_REXX | SIGBREAKF_CTRL_F);
  4380.  
  4381.                                 if(SignalSet & PORTMASK(IconPort))
  4382.                                 {
  4383.                                         /* Pick up application messages. */
  4384.  
  4385.                                     while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  4386.                                     {
  4387.                                             /* Received a double-click? */
  4388.  
  4389.                                         IconTerminated = TRUE;
  4390.  
  4391.                                         ReplyMsg(AppMessage);
  4392.                                     }
  4393.                                 }
  4394.  
  4395.                                     /* Wake up if ARexx command received. */
  4396.  
  4397.                                 if(SignalSet & SIG_REXX)
  4398.                                     while(HandleRexx());
  4399.  
  4400.                                 if(SignalSet & SIGBREAKF_CTRL_F)
  4401.                                     IconTerminated = TRUE;
  4402.                             }
  4403.  
  4404.                                 /* Open the serial driver. */
  4405.  
  4406.                             if(Config -> MiscConfig -> ReleaseDevice)
  4407.                             {
  4408.                                 if(Error = CreateSerial())
  4409.                                 {
  4410.                                     DeleteSerial();
  4411.  
  4412.                                     switch(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_IGNORE_QUIT_TXT),Error))
  4413.                                     {
  4414.                                         case 1:    IconTerminated = FALSE;
  4415.                                             goto IconLoop;
  4416.  
  4417.                                         case 0:    MainTerminated = TRUE;
  4418.                                     }
  4419.                                 }
  4420.                                 else
  4421.                                 {
  4422.                                     if(SerialMessage)
  4423.                                     {
  4424.                                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  4425.  
  4426.                                         SerialMessage = NULL;
  4427.                                     }
  4428.                                 }
  4429.                             }
  4430.  
  4431.                             if(CantQuit && MainTerminated)
  4432.                                 MainTerminated = FALSE;
  4433.  
  4434.                                 /* Create the display. */
  4435.  
  4436.                             if(!MainTerminated)
  4437.                             {
  4438.                                 if(String = CreateDisplay(FALSE))
  4439.                                 {
  4440.                                     if(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_QUIT_TXT),String))
  4441.                                     {
  4442.                                         ClearSerial();
  4443.  
  4444.                                         DeleteSerial();
  4445.  
  4446.                                         IconTerminated = FALSE;
  4447.  
  4448.                                         goto IconLoop;
  4449.                                     }
  4450.                                     else
  4451.                                         MainTerminated = FALSE;
  4452.                                 }
  4453.                                 else
  4454.                                 {
  4455.                                     BumpWindow(Window);
  4456.  
  4457.                                     PubScreenStuff();
  4458.                                 }
  4459.                             }
  4460.                         }
  4461.                         else
  4462.                         {
  4463.                             BlockWindows();
  4464.  
  4465.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  4466.  
  4467.                             ReleaseWindows();
  4468.                         }
  4469.  
  4470.                             /* Remove the application icon. */
  4471.  
  4472.                         RemoveAppIcon(AppIcon);
  4473.  
  4474.                             /* Reply pending messages. */
  4475.  
  4476.                         while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  4477.                             ReplyMsg(AppMessage);
  4478.                     }
  4479.                     else
  4480.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_ADD_APPLICATION_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4481.  
  4482.                     DeleteMsgPort(IconPort);
  4483.                 }
  4484.                 else
  4485.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_CREATE_MSGPORT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4486.  
  4487.                 FreeDiskObject(Icon);
  4488.             }
  4489.             else
  4490.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_TOOL_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4491.         }
  4492.         else
  4493.             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_ICON_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4494.     }
  4495.     else
  4496.         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_WORKBENCH_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4497.  
  4498.     if(!Released)
  4499.         ReleaseWindows();
  4500.  
  4501.         /* Finished! */
  4502.  
  4503.     DoIconify = FALSE;
  4504. }
  4505.  
  4506.     /* HandleOnlineCleanup():
  4507.      *
  4508.      *    Perform offline cleanup tasks.
  4509.      */
  4510.  
  4511. VOID __regargs
  4512. HandleOnlineCleanup(BOOL Hangup)
  4513. {
  4514.     SoundPlay(SOUND_DISCONNECT);
  4515.  
  4516.         /* Execute logoff macro. */
  4517.  
  4518.     if(Config -> CommandConfig -> LogoffMacro[0] && WasOnline)
  4519.         SerialCommand(Config -> CommandConfig -> LogoffMacro);
  4520.  
  4521.     StopCall(FALSE);
  4522.  
  4523.     if(CurrentPay)
  4524.     {
  4525.         if(Hangup)
  4526.             LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_COST_TXT),CreateSum(CurrentPay,TRUE));
  4527.         else
  4528.             LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_COST_TXT),CreateSum(CurrentPay,TRUE));
  4529.     }
  4530.     else
  4531.     {
  4532.         if(Hangup)
  4533.             LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_TXT));
  4534.         else
  4535.             LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
  4536.     }
  4537.  
  4538.     SetDialMenu(TRUE);
  4539.  
  4540.     if(!Hangup)
  4541.         Say(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
  4542.  
  4543.         /* Clear the password. */
  4544.  
  4545.     Password[0]        = 0;
  4546.     UserName[0]        = 0;
  4547.  
  4548.     CurrentBBSName[0]    = 0;
  4549.     CurrentBBSComment[0]    = 0;
  4550.     CurrentBBSNumber[0]    = 0;
  4551.  
  4552.     ObtainSemaphore(&OnlineSemaphore);
  4553.  
  4554.     if(!Config -> SerialConfig -> CheckCarrier)
  4555.         Online = WasOnline = FALSE;
  4556.  
  4557.     ReleaseSemaphore(&OnlineSemaphore);
  4558.  
  4559.     ObtainSemaphore(&PatternSemaphore);
  4560.  
  4561.     ChosenEntry    = NULL;
  4562.     ChosenPattern    = NULL;
  4563.  
  4564.     ReleaseSemaphore(&PatternSemaphore);
  4565.  
  4566.     LimitCount = -1;
  4567.  
  4568.         /* Previous configuration available? */
  4569.  
  4570.     if(BackupConfig)
  4571.     {
  4572.             /* Remember old configuration. */
  4573.  
  4574.         SaveConfig(Config,PrivateConfig);
  4575.  
  4576.             /* Copy configuration. */
  4577.  
  4578.         SaveConfig(BackupConfig,Config);
  4579.  
  4580.             /* Set up new configuration. */
  4581.  
  4582.         ConfigSetup();
  4583.  
  4584.             /* Free old configuration. */
  4585.  
  4586.         DeleteConfiguration(BackupConfig);
  4587.  
  4588.         BackupConfig = NULL;
  4589.     }
  4590.  
  4591.     if(!ResetDisplay && CurrentPay)
  4592.     {
  4593.             /* Reset the text rendering styles, font, etc. in
  4594.              * order to keep the following text from getting
  4595.              * illegible.
  4596.              */
  4597.  
  4598.         SoftReset();
  4599.  
  4600.             /* Display how much we expect
  4601.              * the user will have to pay for
  4602.              * this call.
  4603.              */
  4604.  
  4605.         ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  4606.  
  4607.         CurrentPay = 0;
  4608.     }
  4609.  
  4610.     if(Config -> ModemConfig -> RedialAfterHangup)
  4611.     {
  4612.         if(DialList)
  4613.         {
  4614.             if(DialList -> lh_Head -> ln_Succ)
  4615.             {
  4616.                 ObtainSemaphore(&OnlineSemaphore);
  4617.  
  4618.                 Online = WasOnline = FALSE;
  4619.  
  4620.                 ReleaseSemaphore(&OnlineSemaphore);
  4621.  
  4622.                 DoDial = DIAL_REDIAL;
  4623.             }
  4624.         }
  4625.     }
  4626. }
  4627.  
  4628.     /* HandleFlowChange():
  4629.      *
  4630.      *    Handle data flow scanner information.
  4631.      */
  4632.  
  4633. VOID
  4634. HandleFlowChange()
  4635. {
  4636.     ObtainSemaphore(&OnlineSemaphore);
  4637.  
  4638.     if(Online)
  4639.     {
  4640.         ReleaseSemaphore(&OnlineSemaphore);
  4641.  
  4642.         if(FlowInfo . NoCarrier)
  4643.         {
  4644.             if(Config -> SerialConfig -> CheckCarrier)
  4645.             {
  4646.                     /* Is the carrier still present? */
  4647.  
  4648.                 if(!(GetSerialStatus() & CIAF_COMCD))    // = Carrier detected
  4649.                     FlowInfo . NoCarrier = FALSE;
  4650.             }
  4651.  
  4652.             if(FlowInfo . NoCarrier)
  4653.             {
  4654.                 ObtainSemaphore(&OnlineSemaphore);
  4655.  
  4656.                 if(Online)
  4657.                 {
  4658.                     WasOnline    = Online;
  4659.                     Online        = FALSE;
  4660.                 }
  4661.  
  4662.                 ReleaseSemaphore(&OnlineSemaphore);
  4663.             }
  4664.         }
  4665.     }
  4666.     else
  4667.     {
  4668.         ReleaseSemaphore(&OnlineSemaphore);
  4669.  
  4670.         if(FlowInfo . Voice)
  4671.         {
  4672.             UBYTE DateTimeBuffer[256];
  4673.  
  4674.             FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
  4675.  
  4676.             WakeUp(Window,SOUND_VOICE);
  4677.  
  4678.             ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_VOIC_CALL_TXT),DateTimeBuffer);
  4679.  
  4680.             Say(LocaleString(MSG_TERMMAIN_SAY_INCOMING_VOICE_CALL_TXT));
  4681.         }
  4682.  
  4683.         if(FlowInfo . Ring)
  4684.         {
  4685.             UBYTE DateTimeBuffer[256];
  4686.  
  4687.             FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
  4688.  
  4689.             WakeUp(Window,SOUND_RING);
  4690.  
  4691.             ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_CALL_TXT),DateTimeBuffer);
  4692.  
  4693.             Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  4694.         }
  4695.  
  4696.         if(FlowInfo . Connect)
  4697.         {
  4698.                 /* Are we to check the carrier signal? */
  4699.  
  4700.             if(Config -> SerialConfig -> CheckCarrier)
  4701.             {
  4702.                     /* No carrier signal present? */
  4703.  
  4704.                 if(GetSerialStatus() & CIAF_COMCD)    // = Carrier lost
  4705.                     FlowInfo . Connect = FALSE;
  4706.             }
  4707.  
  4708.             if(FlowInfo . Connect)
  4709.             {
  4710.                 WakeUp(Window,SOUND_CONNECT);
  4711.  
  4712.                 ObtainSemaphore(&OnlineSemaphore);
  4713.  
  4714.                 if(!Online)
  4715.                 {
  4716.                     WasOnline    = Online;
  4717.                     Online        = TRUE;
  4718.                 }
  4719.  
  4720.                 BaudPending = FALSE;
  4721.  
  4722.                 ReleaseSemaphore(&OnlineSemaphore);
  4723.  
  4724.                 SetDialMenu(FALSE);
  4725.             }
  4726.         }
  4727.     }
  4728.  
  4729.         /* Check if we are to prompt the user for
  4730.          * file transfer.
  4731.          */
  4732.  
  4733.     if(FlowInfo . Signature)
  4734.     {
  4735.         WORD Type = FlowInfo . Signature - SCAN_SIGDEFAULTUPLOAD + TRANSFERSIG_DEFAULTUPLOAD;
  4736.  
  4737.         switch(Type)
  4738.         {
  4739.             case TRANSFERSIG_DEFAULTUPLOAD:
  4740.  
  4741.                 BlockWindows();
  4742.  
  4743.                 switch(UploadPanel(TRUE))
  4744.                 {
  4745.                     case UPLOAD_TEXT:
  4746.  
  4747.                         BinaryTransfer = FALSE;
  4748.  
  4749.                         if(!StartXprSend(TRANSFER_TEXT,TRUE))
  4750.                             SerWrite(ZModemCancel,20);
  4751.  
  4752.                         break;
  4753.  
  4754.                     case UPLOAD_BINARY:
  4755.  
  4756.                         BinaryTransfer = TRUE;
  4757.  
  4758.                         if(!StartXprSend(TRANSFER_BINARY,TRUE))
  4759.                             SerWrite(ZModemCancel,20);
  4760.  
  4761.                         break;
  4762.  
  4763.                     case UPLOAD_ABORT:
  4764.  
  4765.                         SerWrite(ZModemCancel,20);
  4766.                         break;
  4767.  
  4768.                     case UPLOAD_BINARY_FROM_LIST:
  4769.  
  4770.                         StartUpload(UPLOAD_BINARY);
  4771.                         break;
  4772.  
  4773.                     case UPLOAD_TEXT_FROM_LIST:
  4774.  
  4775.                         StartUpload(UPLOAD_TEXT);
  4776.                         break;
  4777.                 }
  4778.  
  4779.                 ReleaseWindows();
  4780.  
  4781.                 break;
  4782.  
  4783.             case TRANSFERSIG_DEFAULTDOWNLOAD:
  4784.  
  4785.                 BlockWindows();
  4786.  
  4787.                 switch(UploadPanel(FALSE))
  4788.                 {
  4789.                     case UPLOAD_TEXT:
  4790.  
  4791.                         BinaryTransfer = FALSE;
  4792.  
  4793.                         StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
  4794.  
  4795.                         BinaryTransfer = TRUE;
  4796.  
  4797.                         break;
  4798.  
  4799.                     case UPLOAD_BINARY:
  4800.  
  4801.                         BinaryTransfer = TRUE;
  4802.  
  4803.                         StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
  4804.  
  4805.                         break;
  4806.                 }
  4807.  
  4808.                 ReleaseWindows();
  4809.  
  4810.                 break;
  4811.  
  4812.             case TRANSFERSIG_ASCIIUPLOAD:
  4813.  
  4814.                 BlockWindows();
  4815.  
  4816.                 if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
  4817.                 {
  4818.                     BinaryTransfer = FALSE;
  4819.  
  4820.                     StartXprSend(TRANSFER_ASCII,TRUE);
  4821.  
  4822.                     BinaryTransfer = TRUE;
  4823.                 }
  4824.  
  4825.                 ResetProtocol();
  4826.  
  4827.                 ReleaseWindows();
  4828.  
  4829.                 break;
  4830.  
  4831.             case TRANSFERSIG_ASCIIDOWNLOAD:
  4832.  
  4833.                 BlockWindows();
  4834.  
  4835.                 if(ChangeProtocol(Config -> TransferConfig -> ASCIIDownloadLibrary,Config -> TransferConfig -> ASCIIDownloadType))
  4836.                 {
  4837.                     BinaryTransfer = FALSE;
  4838.  
  4839.                     StartXprReceive(TRANSFER_ASCII,NULL,TRUE);
  4840.  
  4841.                     BinaryTransfer = TRUE;
  4842.                 }
  4843.  
  4844.                 ResetProtocol();
  4845.  
  4846.                 ReleaseWindows();
  4847.  
  4848.                 break;
  4849.  
  4850.             case TRANSFERSIG_TEXTUPLOAD:
  4851.  
  4852.                 BlockWindows();
  4853.  
  4854.                 if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
  4855.                 {
  4856.                     BinaryTransfer = FALSE;
  4857.  
  4858.                     StartXprSend(TRANSFER_TEXT,TRUE);
  4859.  
  4860.                     BinaryTransfer = TRUE;
  4861.                 }
  4862.  
  4863.                 ResetProtocol();
  4864.  
  4865.                 ReleaseWindows();
  4866.  
  4867.                 break;
  4868.  
  4869.             case TRANSFERSIG_TEXTDOWNLOAD:
  4870.  
  4871.                 BlockWindows();
  4872.  
  4873.                 if(ChangeProtocol(Config -> TransferConfig -> TextDownloadLibrary,Config -> TransferConfig -> TextDownloadType))
  4874.                 {
  4875.                     BinaryTransfer = FALSE;
  4876.  
  4877.                     StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
  4878.  
  4879.                     BinaryTransfer = TRUE;
  4880.                 }
  4881.  
  4882.                 ResetProtocol();
  4883.  
  4884.                 ReleaseWindows();
  4885.  
  4886.                 break;
  4887.  
  4888.  
  4889.             case TRANSFERSIG_BINARYUPLOAD:
  4890.  
  4891.                 BlockWindows();
  4892.  
  4893.                 if(ChangeProtocol(Config -> TransferConfig -> BinaryUploadLibrary,Config -> TransferConfig -> BinaryUploadType))
  4894.                 {
  4895.                     BinaryTransfer = TRUE;
  4896.  
  4897.                     StartXprSend(TRANSFER_BINARY,TRUE);
  4898.                 }
  4899.  
  4900.                 ResetProtocol();
  4901.  
  4902.                 ReleaseWindows();
  4903.  
  4904.                 break;
  4905.  
  4906.             case TRANSFERSIG_BINARYDOWNLOAD:
  4907.  
  4908.                 BlockWindows();
  4909.  
  4910.                 if(ChangeProtocol(Config -> TransferConfig -> BinaryDownloadLibrary,Config -> TransferConfig -> BinaryDownloadType))
  4911.                 {
  4912.                     BinaryTransfer = TRUE;
  4913.  
  4914.                     StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
  4915.                 }
  4916.  
  4917.                 ResetProtocol();
  4918.  
  4919.                 ReleaseWindows();
  4920.  
  4921.                 break;
  4922.         }
  4923.     }
  4924.  
  4925.     FlowInit(TRUE);
  4926. }
  4927.  
  4928.     /* HandleSerialReset():
  4929.      *
  4930.      *    Handle serial device reset.
  4931.      */
  4932.  
  4933. VOID
  4934. HandleSerialReset()
  4935. {
  4936.     ClearSerial();
  4937.  
  4938.     DeleteSerial();
  4939.  
  4940.     BlockWindows();
  4941.  
  4942.     ReopenSerial();
  4943.  
  4944.     ReleaseWindows();
  4945. }
  4946.  
  4947.     /* HandleSerialRelease():
  4948.      *
  4949.      *    Release the serial device driver, then reopen it again.
  4950.      */
  4951.  
  4952. VOID
  4953. HandleSerialRelease()
  4954. {
  4955.     APTR    OldPtr = ThisProcess -> pr_WindowPtr;
  4956.     BYTE    Continue,SerialClosed;
  4957.  
  4958.     ThisProcess -> pr_WindowPtr = (APTR)Window;
  4959.  
  4960.         /* This might happen if an ARexx user
  4961.          * released the serial device and
  4962.          * failed to reopen it.
  4963.          */
  4964.  
  4965.     if(ReadPort)
  4966.         SerialClosed = FALSE;
  4967.     else
  4968.         SerialClosed = TRUE;
  4969.  
  4970.     BlockWindows();
  4971.  
  4972.         /* Prevent catastrophes! */
  4973.  
  4974.     if(!Config -> MiscConfig -> ProtectiveMode)
  4975.         Continue = TRUE;
  4976.     else
  4977.     {
  4978.         ObtainSemaphore(&OnlineSemaphore);
  4979.  
  4980.         if(Online && !SerialClosed)
  4981.         {
  4982.             ReleaseSemaphore(&OnlineSemaphore);
  4983.  
  4984.             if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  4985.                 Continue = FALSE;
  4986.             else
  4987.                 Continue = TRUE;
  4988.         }
  4989.         else
  4990.         {
  4991.             ReleaseSemaphore(&OnlineSemaphore);
  4992.  
  4993.             Continue = TRUE;
  4994.         }
  4995.     }
  4996.  
  4997.     if(Continue)
  4998.     {
  4999.         if(SerialClosed)
  5000.             ReopenSerial();
  5001.         else
  5002.         {
  5003.             ClearSerial();
  5004.  
  5005.             DeleteSerial();
  5006.  
  5007.             if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNIT_RESET_AND_RELEASED_TXT),LocaleString(MSG_TERMMAIN_RETURN_QUIT_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber))
  5008.                 ReopenSerial();
  5009.             else
  5010.                 MainTerminated = TRUE;
  5011.         }
  5012.     }
  5013.  
  5014.     ReleaseSerial = FALSE;
  5015.  
  5016.     ThisProcess -> pr_WindowPtr = OldPtr;
  5017.  
  5018.     ReleaseWindows();
  5019. }
  5020.  
  5021.     /* HandleExternalEmulation():
  5022.      *
  5023.      *    Handle external emulation event.
  5024.      */
  5025.  
  5026. VOID
  5027. HandleExternalEmulation()
  5028. {
  5029.     if(!XEmulatorSignal(XEM_IO,XEM_Signal))
  5030.     {
  5031.         CloseEmulator();
  5032.  
  5033.         ResetDisplay = TRUE;
  5034.     }
  5035. }
  5036.  
  5037.     /* HandleSerialCheck():
  5038.      *
  5039.      *    Handle routine checkup actions.
  5040.      */
  5041.  
  5042. BYTE
  5043. HandleSerialCheck()
  5044. {
  5045.         // Attempt to lock the serial device?
  5046.  
  5047.     if(PollODU)
  5048.     {
  5049.             // We don't want to poll too often
  5050.  
  5051.         if(PollODUCount++ == 4)
  5052.         {
  5053.             PollODUCount = 0;
  5054.  
  5055.                 // Still supporting the locking protocol?
  5056.  
  5057.             if(Config -> SerialConfig -> UseOwnDevUnit)
  5058.             {
  5059.                     // Allocate the signal
  5060.  
  5061.                 if((OwnDevBit = AllocSignal(-1)) != -1)
  5062.                 {
  5063.                         // Give it a try
  5064.  
  5065.                     if(!AttemptDevUnit(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,TermIDString,OwnDevBit))
  5066.                     {
  5067.                             // Check
  5068.  
  5069.                         ReopenSerial();
  5070.  
  5071.                         PollODU = FALSE;
  5072.                     }
  5073.                     else
  5074.                     {
  5075.                             // No success
  5076.  
  5077.                         FreeSignal(OwnDevBit);
  5078.  
  5079.                         OwnDevBit = -1;
  5080.                     }
  5081.                 }
  5082.             }
  5083.             else
  5084.                 PollODU = FALSE;
  5085.         }
  5086.     }
  5087.  
  5088.         /* Take a look at the carrier signal. */
  5089.  
  5090.     if(Config -> SerialConfig -> CheckCarrier && WriteRequest)
  5091.     {
  5092.         register UWORD Status = GetSerialStatus();
  5093.  
  5094.         ObtainSemaphore(&OnlineSemaphore);
  5095.  
  5096.             /* Still online? */
  5097.  
  5098.         if(Online)
  5099.         {
  5100.             ReleaseSemaphore(&OnlineSemaphore);
  5101.  
  5102.                 /* Carrier detect signal lost? */
  5103.  
  5104.             if(Status & CIAF_COMCD)    // = Carrier lost
  5105.             {
  5106.                 ObtainSemaphore(&OnlineSemaphore);
  5107.  
  5108.                 if(Online)
  5109.                 {
  5110.                     WasOnline    = Online;
  5111.                     Online        = FALSE;
  5112.                 }
  5113.  
  5114.                 ReleaseSemaphore(&OnlineSemaphore);
  5115.             }
  5116.         }
  5117.         else
  5118.         {
  5119.             ReleaseSemaphore(&OnlineSemaphore);
  5120.  
  5121.                 /* Is the carrier detect signal
  5122.                  * present?
  5123.                  */
  5124.  
  5125.             if(!(Status & CIAF_COMCD))    // = Carrier detected
  5126.             {
  5127.                 ObtainSemaphore(&OnlineSemaphore);
  5128.  
  5129.                 if(!Online)
  5130.                 {
  5131.                     WasOnline    = Online;
  5132.                     Online        = TRUE;
  5133.                 }
  5134.  
  5135.                 ReleaseSemaphore(&OnlineSemaphore);
  5136.  
  5137.                 BaudCount        = 0;
  5138.                 BaudBuffer[0]        = 0;
  5139.                 BaudPending        = FALSE;
  5140.  
  5141.                 CurrentPay        = 0;
  5142.  
  5143.                 ObtainSemaphore(&PatternSemaphore);
  5144.  
  5145.                 ChosenEntry        = NULL;
  5146.                 ChosenPattern        = NULL;
  5147.  
  5148.                 ReleaseSemaphore(&PatternSemaphore);
  5149.  
  5150.                 Password[0]        = 0;
  5151.                 UserName[0]        = 0;
  5152.  
  5153.                 SendStartup        = FALSE;
  5154.  
  5155.                 LimitCount        = -1;
  5156.  
  5157.                 CurrentBBSName[0]    = 0;
  5158.                 CurrentBBSComment[0]    = 0;
  5159.                 CurrentBBSNumber[0]    = 0;
  5160.  
  5161.                 SetDialMenu(FALSE);
  5162.             }
  5163.         }
  5164.     }
  5165.  
  5166.         /* Check online time limit. */
  5167.  
  5168.     if(!LimitCount)
  5169.     {
  5170.         LimitCount = -1;
  5171.  
  5172.         BlockWindows();
  5173.  
  5174.         SendARexxCommand(LimitMacro,TRUE);
  5175.  
  5176.         ReleaseWindows();
  5177.     }
  5178.  
  5179.         /* Flush capture file contents to disk,
  5180.          * this routine is executed each minute
  5181.          * in order to store the captured data.
  5182.          */
  5183.  
  5184.     if(BufferFlushCount-- <= 0)
  5185.     {
  5186.         BufferFlushCount = 60;
  5187.  
  5188.             /* Flush the capture file. */
  5189.  
  5190.         if(FileCapture)
  5191.             BufferFlush(FileCapture);
  5192.     }
  5193.  
  5194.     return(FALSE);
  5195. }
  5196.  
  5197.     /* HandleQueueMsg():
  5198.      *
  5199.      *    Process the special message queue.
  5200.      */
  5201.  
  5202. BYTE
  5203. HandleQueueMsg()
  5204. {
  5205.     struct DataMsg *Item;
  5206.  
  5207.     if(Item = GetMsgItem(SpecialQueue))
  5208.     {
  5209.         struct FileTransferInfo *Info;
  5210.         BYTE             OldEcho;
  5211.  
  5212.         switch(Item -> Type)
  5213.         {
  5214.                 // Output data.
  5215.  
  5216.             case DATAMSGTYPE_WRITE:
  5217.  
  5218.                 SerWrite(Item -> Data,Item -> Size);
  5219.                 break;
  5220.  
  5221.                 // Execute a command.
  5222.  
  5223.             case DATAMSGTYPE_SERIALCOMMAND:
  5224.  
  5225.                 SerialCommand(Item -> Data);
  5226.                 break;
  5227.  
  5228.                 // Execute a command, but don't echo it.
  5229.  
  5230.             case DATAMSGTYPE_SERIALCOMMANDNOECHO:
  5231.  
  5232.                 OldEcho = Config -> SerialConfig -> Duplex;
  5233.  
  5234.                 Config -> SerialConfig -> Duplex = DUPLEX_FULL;
  5235.  
  5236.                 SerialCommand(Item -> Data);
  5237.  
  5238.                 Config -> SerialConfig -> Duplex = OldEcho;
  5239.                 break;
  5240.  
  5241.                 // Output contents of clipboard
  5242.  
  5243.             case DATAMSGTYPE_WRITECLIP:
  5244.  
  5245.                 if(!ClipInput)
  5246.                 {
  5247.                     if(!OpenClip(Item -> Size))
  5248.                         ClipInput = ClipXerox = TRUE;
  5249.                     else
  5250.                         ClipInput = ClipXerox = FALSE;
  5251.                 }
  5252.  
  5253.                     /* Are we reading input from the clipboard? */
  5254.  
  5255.                 if(ClipInput)
  5256.                 {
  5257.                     UBYTE    InputBuffer[257];
  5258.                     WORD    Len;
  5259.  
  5260.                     if((Len = GetClip(InputBuffer,256,TRUE)) < 0)
  5261.                     {
  5262.                         CloseClip();
  5263.  
  5264.                         ClipInput = FALSE;
  5265.  
  5266.                         if(ClipXerox)
  5267.                         {
  5268.                             if(Config -> ClipConfig -> InsertSuffix[0])
  5269.                                 SerialCommand(Config -> ClipConfig -> InsertSuffix);
  5270.  
  5271.                             ClipXerox = FALSE;
  5272.                         }
  5273.  
  5274.                         ClipPrefix = FALSE;
  5275.                     }
  5276.                     else
  5277.                     {
  5278.                         if(!ClipPrefix && ClipXerox)
  5279.                         {
  5280.                             if(Config -> ClipConfig -> InsertPrefix[0])
  5281.                                 SerialCommand(Config -> ClipConfig -> InsertPrefix);
  5282.  
  5283.                             ClipPrefix = TRUE;
  5284.                         }
  5285.  
  5286.                         if(Len > 0)
  5287.                             SendInputTextBuffer(InputBuffer,Len,FALSE,Config -> ClipConfig -> ConvertLF);
  5288.                     }
  5289.                 }
  5290.  
  5291.                 break;
  5292.  
  5293.                 // Start an upload
  5294.  
  5295.             case DATAMSGTYPE_UPLOAD:
  5296.  
  5297.                 if(((struct List *)Item -> Data) -> lh_Head -> ln_Succ)
  5298.                 {
  5299.                     if(Info = AllocFileTransferInfo())
  5300.                     {
  5301.                         struct FileInfoBlock *FileInfo;
  5302.                         LONG FilesFound = 0,Type = Item -> Size;
  5303.  
  5304.                         if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  5305.                         {
  5306.                             BPTR FileLock;
  5307.                             struct List *List;
  5308.                             struct Node *Node,*Next;
  5309.                             APTR OldPtr = ThisProcess -> pr_WindowPtr;
  5310.  
  5311.                             ThisProcess -> pr_WindowPtr = (APTR)-1;
  5312.  
  5313.                             List = (struct List *)Item -> Data;
  5314.  
  5315.                             for(Node = List -> lh_Head ; Next = Node -> ln_Succ ; Node = Next)
  5316.                             {
  5317.                                 if(FileLock = Lock(Node -> ln_Name,ACCESS_READ))
  5318.                                 {
  5319.                                     if(Examine(FileLock,FileInfo))
  5320.                                     {
  5321.                                         if(FileInfo -> fib_DirEntryType < 0)
  5322.                                         {
  5323.                                             if(AddFileTransferNode(Info,Node -> ln_Name,FileInfo -> fib_Size))
  5324.                                                 FilesFound++;
  5325.  
  5326.                                             if(Config -> TransferConfig -> TransferIcons)
  5327.                                             {
  5328.                                                 BPTR InfoLock;
  5329.  
  5330.                                                 strcpy(SharedBuffer,Node -> ln_Name);
  5331.  
  5332.                                                 strcat(SharedBuffer,".info");
  5333.  
  5334.                                                 if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
  5335.                                                 {
  5336.                                                     if(Examine(InfoLock,FileInfo))
  5337.                                                     {
  5338.                                                         if(FileInfo -> fib_DirEntryType < 0)
  5339.                                                         {
  5340.                                                             if(AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  5341.                                                                 FilesFound++;
  5342.                                                         }
  5343.                                                     }
  5344.  
  5345.                                                     UnLock(InfoLock);
  5346.                                                 }
  5347.                                             }
  5348.  
  5349.                                             Remove(Node);
  5350.  
  5351.                                             FreeVecPooled(Node);
  5352.                                         }
  5353.                                     }
  5354.  
  5355.                                     UnLock(FileLock);
  5356.                                 }
  5357.                             }
  5358.  
  5359.                             ThisProcess -> pr_WindowPtr = OldPtr;
  5360.  
  5361.                             FreeDosObject(DOS_FIB,FileInfo);
  5362.                         }
  5363.  
  5364.                         DeleteMsgItem(Item);
  5365.  
  5366.                         Item = NULL;
  5367.  
  5368.                         if(FilesFound)
  5369.                         {
  5370.                             BlockWindows();
  5371.  
  5372.                             SortFileTransferInfo(Info);
  5373.  
  5374.                             switch(Type)
  5375.                             {
  5376.                                 case UPLOAD_BINARY:
  5377.  
  5378.                                     BinaryTransfer        = TRUE;
  5379.                                     FileTransferInfo    = Info;
  5380.  
  5381.                                     StartXprSendFromList(TRANSFER_BINARY,TRUE);
  5382.  
  5383.                                     break;
  5384.  
  5385.                                 case UPLOAD_TEXT:
  5386.  
  5387.                                     BinaryTransfer        = FALSE;
  5388.                                     FileTransferInfo    = Info;
  5389.  
  5390.                                     StartXprSendFromList(TRANSFER_TEXT,TRUE);
  5391.  
  5392.                                     break;
  5393.                             }
  5394.  
  5395.                             ReleaseWindows();
  5396.                         }
  5397.                         else
  5398.                             FreeFileTransferInfo(Info);
  5399.                     }
  5400.                 }
  5401.                 else
  5402.                 {
  5403.                     UBYTE Type = Item -> Size;
  5404.  
  5405.                     DeleteMsgItem(Item);
  5406.  
  5407.                     Item = NULL;
  5408.  
  5409.                     if(Type == UPLOAD_BINARY)
  5410.                     {
  5411.                         BinaryTransfer = TRUE;
  5412.  
  5413.                         if(!StartXprSend(TRANSFER_BINARY,TRUE))
  5414.                             SerWrite(ZModemCancel,20);
  5415.                     }
  5416.                     else
  5417.                     {
  5418.                         BinaryTransfer = FALSE;
  5419.  
  5420.                         if(!StartXprSend(TRANSFER_TEXT,TRUE))
  5421.                             SerWrite(ZModemCancel,20);
  5422.                     }
  5423.                 }
  5424.  
  5425.                 break;
  5426.  
  5427.                 // ARexx script execution finished.
  5428.  
  5429.             case DATAMSGTYPE_COMMANDDONE:
  5430.  
  5431.                 if(CantQuit > 0)
  5432.                     CantQuit--;
  5433.  
  5434.                 BumpWindow(Window);
  5435.  
  5436.                 ReleaseWindows();
  5437.  
  5438.                 ObtainSemaphore(&ARexxQueueSemaphore);
  5439.  
  5440.                 ARexxRunning = FALSE;
  5441.  
  5442.                 if(ARexxQueue . lh_Head -> ln_Succ)
  5443.                 {
  5444.                     struct Node *Node;
  5445.  
  5446.                     if(Node = RemHead(&ARexxQueue))
  5447.                     {
  5448.                         ReleaseSemaphore(&ARexxQueueSemaphore);
  5449.  
  5450.                         SendARexxCommand(Node -> ln_Name,FALSE);
  5451.  
  5452.                         FreeNode(Node);
  5453.                     }
  5454.                     else
  5455.                         ReleaseSemaphore(&ARexxQueueSemaphore);
  5456.                 }
  5457.                 else
  5458.                     ReleaseSemaphore(&ARexxQueueSemaphore);
  5459.  
  5460.                 break;
  5461.  
  5462.                 // Call a menu item
  5463.  
  5464.             case DATAMSGTYPE_MENU:
  5465.  
  5466.                 HandleMenuCode((ULONG)Item -> Size,(ULONG)Item -> Data);
  5467.  
  5468.                 break;
  5469.  
  5470.                 // Rendezvous with external process
  5471.  
  5472.             case DATAMSGTYPE_RENDEZVOUS:
  5473.  
  5474.                 if(ReadRequest && WriteRequest)
  5475.                 {
  5476.                         // Abort serial I/O processing
  5477.  
  5478.                     ClearSerial();
  5479.  
  5480.                     BlockWindows();
  5481.  
  5482.                         // Return the message, caution, we're not ready yet
  5483.  
  5484.                     Forbid();
  5485.  
  5486.                     DeleteMsgItem(Item);
  5487.  
  5488.                     Item = NULL;
  5489.  
  5490.                         // Prepare to wait...
  5491.  
  5492.                     ClrSignal(SIG_HANDSHAKE);
  5493.  
  5494.                     Wait(SIG_HANDSHAKE);
  5495.  
  5496.                         // Pick up the queue
  5497.  
  5498.                     RestartSerial(FALSE);
  5499.  
  5500.                     Permit();
  5501.  
  5502.                     ReleaseWindows();
  5503.                 }
  5504.  
  5505.                 break;
  5506.         }
  5507.  
  5508.         if(Item)
  5509.             DeleteMsgItem(Item);
  5510.  
  5511.         return(TRUE);
  5512.     }
  5513.     else
  5514.         return(FALSE);
  5515. }
  5516.  
  5517.     /* HandleOwnDevUnit():
  5518.      *
  5519.      *    Deal with the OwnDevUnit signal notification.
  5520.      */
  5521.  
  5522. BYTE
  5523. HandleOwnDevUnit()
  5524. {
  5525.     ObtainSemaphore(&OnlineSemaphore);
  5526.  
  5527.     if(!Online || !ReadPort)
  5528.     {
  5529.         ReleaseSemaphore(&OnlineSemaphore);
  5530.  
  5531.         if(Config -> SerialConfig -> SatisfyODURequests == ODU_RELEASE)
  5532.             HandleSerialRelease();
  5533.  
  5534.         if(Config -> SerialConfig -> SatisfyODURequests == ODU_WAIT)
  5535.         {
  5536.             APTR    OldPtr = ThisProcess -> pr_WindowPtr;
  5537.             BYTE    Continue,SerialClosed;
  5538.  
  5539.             ThisProcess -> pr_WindowPtr = (APTR)Window;
  5540.  
  5541.                 /* This might happen if an ARexx user
  5542.                  * released the serial device and
  5543.                  * failed to reopen it.
  5544.                  */
  5545.  
  5546.             if(ReadPort)
  5547.                 SerialClosed = FALSE;
  5548.             else
  5549.                 SerialClosed = TRUE;
  5550.  
  5551.             BlockWindows();
  5552.  
  5553.                 /* Prevent catastrophes! */
  5554.  
  5555.             ObtainSemaphore(&OnlineSemaphore);
  5556.  
  5557.             if(Online && !SerialClosed)
  5558.             {
  5559.                 ReleaseSemaphore(&OnlineSemaphore);
  5560.  
  5561.                 if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  5562.                     Continue = FALSE;
  5563.                 else
  5564.                     Continue = TRUE;
  5565.             }
  5566.             else
  5567.             {
  5568.                 ReleaseSemaphore(&OnlineSemaphore);
  5569.  
  5570.                 Continue = TRUE;
  5571.             }
  5572.  
  5573.             if(Continue)
  5574.             {
  5575.                 if(!SerialClosed)
  5576.                 {
  5577.                     ClearSerial();
  5578.  
  5579.                     DeleteSerial();
  5580.  
  5581.                 }
  5582.             }
  5583.  
  5584.             ThisProcess -> pr_WindowPtr = OldPtr;
  5585.  
  5586.             ReleaseWindows();
  5587.  
  5588.                 // Start polling for the device to become
  5589.                 // available again
  5590.  
  5591.             PollODU = TRUE;
  5592.         }
  5593.     }
  5594.     else
  5595.         ReleaseSemaphore(&OnlineSemaphore);
  5596.  
  5597.     return(FALSE);
  5598. }
  5599.